Enhance BulkDispatchWorkflows Activity with Support for Multiple Input Keys and Customizable Input Key (#5182)
* Add PublicAPI attribute to ActivityExecutionContext The 'PublicAPI' attribute has been added to the ActivityExecutionContext class. This signals that this class is part of our public API and should not be modified in a way that violates backward compatibility. Furthermore, the 'RequiresUnreferencedCode' attributes were removed from the 'CompleteActivityAsync' and 'CompleteActivityWithOutcomesAsync' methods, as these methods no longer need them. * Add merge function to DictionaryExtensions A new merge function has been added to the DictionaryExtensions. This function combines the contents of two dictionaries, prioritizing the keys and values from the second dictionary whenever there is a collision. * Add default item input key in BulkDispatchWorkflows The code has been adjusted to include a default input item key in the BulkDispatchWorkflows module. This key will be used for the item input when dispatching workflows, unless the Items field contains a list of dictionaries. Additionally, modifications have been made to convert the item into an input dictionary if it isn't already one and merge this with the input dictionary. * Update Merge method documentation in DictionaryExtensions The commit adds a critical detail about dictionary operation in the method summary. It clearly states that during the merge operation, the value from the 'other' dictionary overwrites the value in the target dictionary when the same key exists in both.
This commit is contained in:
parent
c39f2c13fd
commit
31092f8d81
|
|
@ -1,4 +1,3 @@
|
|||
using System.Diagnostics.CodeAnalysis;
|
||||
using Elsa.Extensions;
|
||||
using Elsa.Workflows.Activities.Flowchart.Models;
|
||||
using Elsa.Workflows.Contracts;
|
||||
|
|
@ -11,7 +10,6 @@ public partial class ActivityExecutionContext
|
|||
/// <summary>
|
||||
/// Complete the current activity. This should only be called by activities that explicitly suppress automatic-completion.
|
||||
/// </summary>
|
||||
[RequiresUnreferencedCode("The activity may be serialized and executed in a different context.")]
|
||||
public async ValueTask CompleteActivityAsync(object? result = default)
|
||||
{
|
||||
var outcomes = result as Outcomes;
|
||||
|
|
@ -93,7 +91,6 @@ public partial class ActivityExecutionContext
|
|||
/// <summary>
|
||||
/// Complete the current activity with the specified outcomes.
|
||||
/// </summary>
|
||||
[RequiresUnreferencedCode("The activity may be serialized and executed in a different context.")]
|
||||
public ValueTask CompleteActivityWithOutcomesAsync(params string[] outcomes)
|
||||
{
|
||||
return CompleteActivityAsync(new Outcomes(outcomes));
|
||||
|
|
|
|||
|
|
@ -10,12 +10,14 @@ using Elsa.Workflows.Memory;
|
|||
using Elsa.Workflows.Models;
|
||||
using Elsa.Workflows.Options;
|
||||
using Elsa.Workflows.Services;
|
||||
using JetBrains.Annotations;
|
||||
|
||||
namespace Elsa.Workflows;
|
||||
|
||||
/// <summary>
|
||||
/// Represents the context of an activity execution.
|
||||
/// </summary>
|
||||
[PublicAPI]
|
||||
public partial class ActivityExecutionContext : IExecutionContext
|
||||
{
|
||||
private readonly ISystemClock _systemClock;
|
||||
|
|
|
|||
|
|
@ -65,6 +65,16 @@ public static class DictionaryExtensions
|
|||
dictionary.Add(key, value);
|
||||
return dictionary;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Merges the specified dictionary with the other dictionary.
|
||||
/// When a key exists in both dictionaries, the value in the other dictionary will overwrite the value in the specified dictionary.
|
||||
/// </summary>
|
||||
public static void Merge(this IDictionary<string, object> dictionary, IDictionary<string, object> other)
|
||||
{
|
||||
foreach (var (key, value) in other)
|
||||
dictionary[key] = value;
|
||||
}
|
||||
|
||||
private static T? ConvertValue<T>(object? value) => value.ConvertTo<T>();
|
||||
}
|
||||
|
|
@ -55,19 +55,25 @@ public class BulkDispatchWorkflows : Activity
|
|||
[Input(Description = "The data source to use for dispatching the workflows.")]
|
||||
public Input<object> Items { get; set; } = default!;
|
||||
|
||||
/// <summary>
|
||||
/// The default key to use for the item input. Will not be used if the Items contain a list of dictionaries.
|
||||
/// </summary>
|
||||
[Input(Description = "The default key to use for the input name when sending the current item to the dispatched workflow. Will not be used if the Items field contain a list of dictionaries", DefaultValue = "Item")]
|
||||
public Input<string> DefaultItemInputKey { get; set; } = new("Item");
|
||||
|
||||
/// <summary>
|
||||
/// The correlation ID to associate the workflow with.
|
||||
/// </summary>
|
||||
[Input(
|
||||
DisplayName = "Correlation ID Function",
|
||||
Description = "A function to compute the correlation ID to associate a dispatched workflow with. Receives the current item as an argument called Item.",
|
||||
Description = "A function to compute the correlation ID to associate a dispatched workflow with.",
|
||||
AutoEvaluate = false)]
|
||||
public Input<string?>? CorrelationIdFunction { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// The input to send to the workflows.
|
||||
/// </summary>
|
||||
[Input(Description = """Additional input to send to the workflows being dispatched. The "Item" key is reserved and should not be used.""")]
|
||||
[Input(Description = "Additional input to send to the workflows being dispatched.")]
|
||||
public Input<IDictionary<string, object>?> Input { get; set; } = default!;
|
||||
|
||||
/// <summary>
|
||||
|
|
@ -102,7 +108,6 @@ public class BulkDispatchWorkflows : Activity
|
|||
public IActivity? ChildFaulted { get; set; }
|
||||
|
||||
/// <inheritdoc />
|
||||
[RequiresUnreferencedCode("Calls Elsa.Expressions.Helpers.ObjectConverter.ConvertTo<T>(ObjectConverterOptions)")]
|
||||
protected override async ValueTask ExecuteAsync(ActivityExecutionContext context)
|
||||
{
|
||||
var waitForCompletion = WaitForCompletion.GetOrDefault(context);
|
||||
|
|
@ -162,20 +167,24 @@ public class BulkDispatchWorkflows : Activity
|
|||
var parentInstanceId = context.WorkflowExecutionContext.Id;
|
||||
var input = Input.GetOrDefault(context) ?? new Dictionary<string, object>();
|
||||
var channelName = ChannelName.GetOrDefault(context);
|
||||
var defaultInputItemKey = DefaultItemInputKey.GetOrDefault(context, () => "Item")!;
|
||||
var properties = new Dictionary<string, object>
|
||||
{
|
||||
["ParentInstanceId"] = parentInstanceId
|
||||
};
|
||||
|
||||
var itemAsInputDictionary = item as IDictionary<string, object> ?? new Dictionary<string, object>
|
||||
{
|
||||
[defaultInputItemKey] = item
|
||||
};
|
||||
|
||||
var evaluatorOptions = new ExpressionEvaluatorOptions
|
||||
{
|
||||
Arguments = new Dictionary<string, object>
|
||||
{
|
||||
["Item"] = item
|
||||
}
|
||||
Arguments = itemAsInputDictionary
|
||||
};
|
||||
|
||||
input["ParentInstanceId"] = parentInstanceId;
|
||||
input["Item"] = item;
|
||||
input.Merge(itemAsInputDictionary);
|
||||
|
||||
var workflowDispatcher = context.GetRequiredService<IWorkflowDispatcher>();
|
||||
var identityGenerator = context.GetRequiredService<IIdentityGenerator>();
|
||||
|
|
@ -198,7 +207,7 @@ public class BulkDispatchWorkflows : Activity
|
|||
};
|
||||
|
||||
var dispatchResponse = await workflowDispatcher.DispatchAsync(request, options, context.CancellationToken);
|
||||
|
||||
|
||||
if (!dispatchResponse.Succeeded)
|
||||
throw new FaultException(dispatchResponse.ErrorMessage);
|
||||
|
||||
|
|
|
|||
Loading…
Reference in a new issue