diff --git a/src/modules/Elsa.Workflows.Core/Extensions/ActivityExecutionContextExtensions.cs b/src/modules/Elsa.Workflows.Core/Extensions/ActivityExecutionContextExtensions.cs index 91740adde..f229bee04 100644 --- a/src/modules/Elsa.Workflows.Core/Extensions/ActivityExecutionContextExtensions.cs +++ b/src/modules/Elsa.Workflows.Core/Extensions/ActivityExecutionContextExtensions.cs @@ -93,6 +93,31 @@ public static partial class ActivityExecutionContextExtensions public static Variable SetVariable(this ActivityExecutionContext context, string name, object? value, Action? configure = null) => context.ExpressionExecutionContext.SetVariable(name, value, configure); + public static Variable SetDynamicVariable(this ActivityExecutionContext context, string name, T value, Action? configure = null) + { + // Check if a predefined variable already exists. + var predefinedVariable = context.ExpressionExecutionContext.GetVariable(name); + + if (predefinedVariable != null) + { + context.SetVariable(name, value); + return predefinedVariable; + } + + // No predefined variable exists, so we will add a dynamic variable to the current container in scope. + var container = context.FindParentWithVariableContainer(); + + if (container == null) + throw new("No parent variable container found"); + + var existingVariable = container.DynamicVariables.FirstOrDefault(x => x.Name == name); + + if (existingVariable == null) + container.DynamicVariables.Add(new Variable(name, value)); + + return context.SetVariable(name, value); + } + /// /// Gets a workflow variable by name. /// @@ -140,7 +165,7 @@ public static partial class ActivityExecutionContextExtensions { var activity = node.Activity; var activityDescriptor = await activityRegistryLookup.FindAsync(activity.Type, activity.Version); - if (activityDescriptor != null && activityDescriptor.Outputs.Any()) + if (activityDescriptor != null && activityDescriptor.Outputs.Any()) yield return (activity, activityDescriptor); } } @@ -188,7 +213,10 @@ public static partial class ActivityExecutionContextExtensions /// public static async ValueTask SendSignalAsync(this ActivityExecutionContext context, object signal) { - var receivingContexts = new[] { context }.Concat(context.GetAncestors()).ToList(); + var receivingContexts = new[] + { + context + }.Concat(context.GetAncestors()).ToList(); var logger = context.GetRequiredService>(); var signalType = signal.GetType(); var signalTypeName = signalType.Name; @@ -243,7 +271,7 @@ public static partial class ActivityExecutionContextExtensions // Send a signal. await context.SendSignalAsync(new ScheduleActivityOutcomes(outcomes)); } - + /// /// Cancel the activity. For blocking activities, it means their bookmarks will be removed. For job activities, the background work will be cancelled. /// @@ -300,7 +328,7 @@ public static partial class ActivityExecutionContextExtensions return null; } - + /// /// Returns a flattened list of the current context's ancestors. ///