< Summary

Information
Class: Elsa.Extensions.ExpressionExecutionContextExtensions
Assembly: Elsa.Workflows.Core
File(s): /home/runner/work/elsa-core/elsa-core/src/modules/Elsa.Workflows.Core/Extensions/ExpressionExecutionContextExtensions.cs
Line coverage
73%
Covered lines: 146
Uncovered lines: 54
Coverable lines: 200
Total lines: 578
Line coverage: 73%
Branch coverage
70%
Covered branches: 78
Total branches: 110
Branch coverage: 70.9%
Method coverage

Feature is only available for sponsors

Upgrade to PRO version

Metrics

File(s)

/home/runner/work/elsa-core/elsa-core/src/modules/Elsa.Workflows.Core/Extensions/ExpressionExecutionContextExtensions.cs

#LineLine coverage
 1using System.Collections;
 2using System.Text.Json;
 3using System.Text.Json.Serialization;
 4using Elsa.Common;
 5using Elsa.Expressions.Helpers;
 6using Elsa.Expressions.Models;
 7using Elsa.Workflows;
 8using Elsa.Workflows.Activities;
 9using Elsa.Workflows.Memory;
 10using Elsa.Workflows.Models;
 11using Humanizer;
 12
 13// ReSharper disable once CheckNamespace
 14namespace Elsa.Extensions;
 15
 16/// <summary>
 17/// Provides extensions on <see cref="ExpressionExecutionContext"/>
 18/// </summary>
 19public static class ExpressionExecutionContextExtensions
 20{
 21    /// <summary>
 22    /// The key used to store the <see cref="WorkflowExecutionContext"/> in the <see cref="ExpressionExecutionContext.Tr
 23    /// </summary>
 524    public static readonly object WorkflowExecutionContextKey = new();
 25
 26    /// <summary>
 27    /// The key used to store the <see cref="ActivityExecutionContext"/> in the <see cref="ExpressionExecutionContext.Tr
 28    /// </summary>
 529    public static readonly object ActivityExecutionContextKey = new();
 30
 31    /// <summary>
 32    /// The key used to store the input in the <see cref="ExpressionExecutionContext.TransientProperties"/> dictionary.
 33    /// </summary>
 534    public static readonly object InputKey = new();
 35
 36    /// <summary>
 37    /// The key used to store the workflow in the <see cref="ExpressionExecutionContext.TransientProperties"/> dictionar
 38    /// </summary>
 539    public static readonly object WorkflowKey = new();
 40
 41    /// <summary>
 42    /// The key used to store the activity in the <see cref="ExpressionExecutionContext.TransientProperties"/> dictionar
 43    /// </summary>
 544    public static readonly object ActivityKey = new();
 45
 46    /// <summary>
 47    /// Creates a dictionary for the specified <see cref="WorkflowExecutionContext"/> and <see cref="ActivityExecutionCo
 48    /// </summary>
 49    public static IDictionary<object, object> CreateActivityExecutionContextPropertiesFrom(WorkflowExecutionContext work
 407750        new Dictionary<object, object>
 407751        {
 407752            [WorkflowExecutionContextKey] = workflowExecutionContext,
 407753            [InputKey] = input,
 407754            [WorkflowKey] = workflowExecutionContext.Workflow,
 407755        };
 56
 57    /// <summary>
 58    /// Creates a dictionary for the specified <see cref="WorkflowExecutionContext"/> and <see cref="ActivityExecutionCo
 59    /// </summary>
 60    public static IDictionary<object, object> CreateTriggerIndexingPropertiesFrom(Workflow workflow, IDictionary<string,
 30461        new Dictionary<object, object>
 30462        {
 30463            [WorkflowKey] = workflow,
 30464            [InputKey] = input
 30465        };
 66
 67    /// <param name="context">The context to start searching from.</param>
 68    extension(ExpressionExecutionContext context)
 69    {
 70        /// <summary>
 71        /// Returns the <see cref="Workflow"/> of the specified <see cref="ExpressionExecutionContext"/>
 72        /// </summary>
 7573        public bool TryGetWorkflowExecutionContext(out WorkflowExecutionContext workflowExecutionContext) => context.Tra
 74
 75        /// <summary>
 76        /// Returns the <see cref="WorkflowExecutionContext"/> of the specified <see cref="ExpressionExecutionContext"/>
 77        /// </summary>
 78        public WorkflowExecutionContext GetWorkflowExecutionContext()
 79        {
 10780            return context.TransientProperties.TryGetValue(WorkflowExecutionContextKey, out var value)
 10781                ? (WorkflowExecutionContext)value
 10782                : throw new InvalidOperationException("WorkflowExecutionContext not found. This value exists only on act
 83        }
 84
 85        /// <summary>
 86        /// Returns the <see cref="ActivityExecutionContext"/> of the specified <see cref="ExpressionExecutionContext"/>
 87        /// </summary>
 88        public ActivityExecutionContext GetActivityExecutionContext()
 89        {
 211790            return context.TransientProperties.TryGetValue(ActivityExecutionContextKey, out var value)
 211791                ? (ActivityExecutionContext)value
 211792                : throw new InvalidOperationException("ActivityExecutionContext not found. This value exists only on act
 93        }
 94
 95        /// <summary>
 96        /// Returns the <see cref="ActivityExecutionContext"/> of the specified <see cref="ExpressionExecutionContext"/>
 97        /// </summary>
 17398        public bool TryGetActivityExecutionContext(out ActivityExecutionContext activityExecutionContext) => context.Tra
 99
 100        /// <summary>
 101        /// Returns the <see cref="Activity"/> of the specified <see cref="ExpressionExecutionContext"/>
 102        /// </summary>
 0103        public IActivity GetActivity() => (IActivity)context.TransientProperties[ActivityKey];
 104
 105        /// <summary>
 106        /// Returns the value of the specified input.
 107        /// </summary>
 1678108        public T? Get<T>(Input<T>? input) => input != null ? context.GetBlock(input.MemoryBlockReference).Value.ConvertT
 109
 110        /// <summary>
 111        /// Returns the value of the specified output.
 112        /// </summary>
 0113        public T? Get<T>(Output output) => context.GetBlock(output.MemoryBlockReference).Value.ConvertTo<T>();
 114
 115        /// <summary>
 116        /// Returns the value of the specified output.
 117        /// </summary>
 0118        public object? Get(Output output) => context.GetBlock(output.MemoryBlockReference).Value;
 119
 120        /// <summary>
 121        /// Returns the value of the variable with the specified name.
 122        /// </summary>
 123        public T? GetVariable<T>(string name)
 124        {
 103125            var block = context.GetVariableBlock(name);
 103126            return (T?)block?.Value;
 127        }
 128
 129        /// <summary>
 130        /// Returns the variable with the specified name.
 131        /// </summary>
 132        public Variable? GetVariable(string name, bool localScopeOnly = false)
 133        {
 29134            var block = context.GetVariableBlock(name, localScopeOnly);
 29135            return block?.Metadata is VariableBlockMetadata metadata ? metadata.Variable : null;
 136        }
 137
 138        private MemoryBlock? GetVariableBlock(string name, bool localScopeOnly = false)
 139        {
 946140            foreach (var block in context.Memory.Blocks.Where(b => b.Value.Metadata is VariableBlockMetadata))
 141            {
 181142                var metadata = block.Value.Metadata as VariableBlockMetadata;
 181143                if (metadata!.Variable.Name == name)
 120144                    return block.Value;
 145            }
 146
 127147            return localScopeOnly ? null : context.ParentContext?.GetVariableBlock(name);
 148        }
 149
 150        /// <summary>
 151        /// Creates a named variable in the context.
 152        /// </summary>
 153        public Variable CreateVariable<T>(string name, T? value, Type? storageDriverType = null, Action<MemoryBlock>? co
 154        {
 7155            var existingVariable = context.GetVariable(name, localScopeOnly: true);
 156
 7157            if (existingVariable != null)
 1158                throw new($"Variable {name} already exists in the context.");
 159
 6160            var variable = new Variable(name, value)
 6161            {
 6162                StorageDriverType = storageDriverType ?? typeof(WorkflowInstanceStorageDriver)
 6163            };
 164
 6165            var parsedValue = variable.ParseValue(value);
 166
 167            // Find the first parent context that has a variable container.
 168            // If not found, use the current context.
 6169            var variableContainerContext = context.GetVariableContainerContext();
 170
 6171            variableContainerContext.Set(variable, parsedValue, configure);
 6172            return variable;
 173        }
 174
 175        /// <summary>
 176        /// Returns the first parent context that contains a variable container.
 177        /// </summary>
 178        public ExpressionExecutionContext GetVariableContainerContext()
 179        {
 6180            return context.FindParent(x =>
 6181            {
 10182                var activityExecutionContext = x.TryGetActivityExecutionContext(out var activityExecutionContextResult) 
 10183                return activityExecutionContext?.Activity is IVariableContainer;
 6184            }) ?? context;
 185        }
 186
 187        /// <summary>
 188        /// Sets the value of a named variable in the context.
 189        /// </summary>
 190        public Variable SetVariable<T>(string name, T? value, Action<MemoryBlock>? configure = null)
 191        {
 15192            var variable = context.GetVariable(name);
 193
 15194            if (variable == null)
 4195                return context.CreateVariable(name, value, configure: configure);
 196
 197            // Get the context where the variable is defined.
 11198            var contextWithVariable = context.FindContextContainingBlock(variable.Id) ?? context;
 199
 200            // Set the value on the variable.
 11201            var parsedValue = variable.ParseValue(value);
 11202            variable.Set(contextWithVariable, parsedValue, configure);
 203
 204            // Return the variable.
 11205            return variable;
 206        }
 207
 208        /// <summary>
 209        /// Sets the output to the specified value.
 210        /// </summary>
 211        public void Set(Output? output, object? value, Action<MemoryBlock>? configure = null)
 212        {
 1722213            if (output != null)
 214            {
 215                // Set the value on the output.
 81216                var outputMemoryBlockReference = output.MemoryBlockReference();
 81217                var parsedValue = output.ParseValue(value);
 81218                context.Set(outputMemoryBlockReference, parsedValue, configure);
 219
 220                // If the referenced output is a workflow output definition, set the value on the workflow execution con
 81221                var workflowExecutionContext = context.GetWorkflowExecutionContext();
 81222                var workflow = workflowExecutionContext.Workflow;
 84223                var workflowOutputDefinition = workflow.Outputs.FirstOrDefault(x => x.Name == outputMemoryBlockReference
 224
 81225                if (workflowOutputDefinition != null)
 1226                    workflowExecutionContext.Output[workflowOutputDefinition.Name] = value!;
 227            }
 1722228        }
 229
 230        /// <summary>
 231        /// Sets an already converted value on the destination referenced by the specified output.
 232        /// </summary>
 233        public void SetBoundValue(Output output, object? value)
 234        {
 5235            var outputMemoryBlockReference = output.MemoryBlockReference();
 5236            context.Set(outputMemoryBlockReference, value);
 237
 5238            var workflowExecutionContext = context.GetWorkflowExecutionContext();
 8239            var workflowOutputDefinition = workflowExecutionContext.Workflow.Outputs.FirstOrDefault(x => x.Name == outpu
 240
 5241            if (workflowOutputDefinition != null)
 2242                workflowExecutionContext.Output[workflowOutputDefinition.Name] = value!;
 5243        }
 244
 245        /// <summary>
 246        /// Returns a dictionary of memory block keys and values across scopes.
 247        /// </summary>
 248        public IDictionary<string, object> ReadAndFlattenMemoryBlocks() =>
 5249            context.FlattenMemoryBlocks().ToDictionary(x => x.Key, x => x.Value.Value!);
 250
 251        /// <summary>
 252        /// Returns a dictionary of memory blocks across scopes.
 253        /// </summary>
 254        public IDictionary<string, MemoryBlock> FlattenMemoryBlocks()
 255        {
 1256            var currentContext = context;
 1257            var memoryBlocks = new Dictionary<string, MemoryBlock>();
 258
 3259            while (currentContext != null)
 260            {
 2261                var register = currentContext.Memory;
 262
 8263                foreach (var entry in register.Blocks)
 2264                    memoryBlocks.TryAdd(entry.Key, entry.Value);
 265
 2266                currentContext = currentContext.ParentContext;
 267            }
 268
 1269            return memoryBlocks;
 270        }
 271
 272        /// <summary>
 273        /// Returns a the first context that contains a memory block with the specified ID.
 274        /// </summary>
 275        public ExpressionExecutionContext? FindContextContainingBlock(string blockId)
 276        {
 1345277            return context.FindParent(x => x.Memory.HasBlock(blockId));
 278        }
 279
 280        /// <summary>
 281        /// Returns the first context in the hierarchy that matches the specified predicate.
 282        /// </summary>
 283        /// <param name="predicate">The predicate to match.</param>
 284        /// <returns>The first context that matches the predicate or <c>null</c> if no match was found.</returns>
 285        public ExpressionExecutionContext? FindParent(Func<ExpressionExecutionContext, bool> predicate)
 286        {
 391287            var currentContext = context;
 288
 1231289            while (currentContext != null)
 290            {
 970291                if (predicate(currentContext))
 130292                    return currentContext;
 293
 840294                currentContext = currentContext.ParentContext;
 295            }
 296
 261297            return null;
 298        }
 299
 300        /// <summary>
 301        /// Returns the value of the specified variable.
 302        /// </summary>
 303        public object GetVariableInScope(string variableName)
 304        {
 2305            var variable = context.GetVariable(variableName);
 2306            var value = variable?.Get(context);
 307
 2308            return ConvertIEnumerableToArray(value);
 309        }
 310
 311        /// <summary>
 312        /// Gets all variables names in scope.
 313        /// </summary>
 314        public IEnumerable<string> GetVariableNamesInScope() =>
 38315            context.EnumerateVariablesInScope()
 36316                .Select(x => x.Name)
 36317                .Where(x => !string.IsNullOrWhiteSpace(x))
 38318                .Distinct();
 319
 320        /// <summary>
 321        /// Gets all variables in scope.
 322        /// </summary>
 323        public IEnumerable<Variable> GetVariablesInScope() =>
 0324            context.EnumerateVariablesInScope()
 0325                .Where(x => !string.IsNullOrWhiteSpace(x.Name))
 0326                .DistinctBy(x => x.Name);
 327
 328        /// <summary>
 329        /// Sets the value of a named variable in the context.
 330        /// </summary>
 331        public void SetVariableInScope(string variableName, object? value)
 332        {
 2333            var q = from v in context.EnumerateVariablesInScope()
 2334                where v.Name == variableName
 2335                where v.TryGet(context, out _)
 2336                select v;
 337
 2338            var variable = q.FirstOrDefault();
 339
 2340            if (variable != null)
 2341                variable.Set(context, value);
 342
 2343            if (variable == null)
 0344                context.CreateVariable(variableName, value);
 2345        }
 346
 347        /// <summary>
 348        /// Enumerates all variables in scope.
 349        /// </summary>
 350        public IEnumerable<Variable> EnumerateVariablesInScope()
 351        {
 51352            var currentScope = context;
 353
 161354            while (currentScope != null)
 355            {
 122356                if (!currentScope.TryGetActivityExecutionContext(out var activityExecutionContext))
 357                {
 41358                    var variables = currentScope.Memory.Blocks.Values
 359                        .Where(x => x.Metadata is VariableBlockMetadata)
 360                        .Select(x => x.Metadata as VariableBlockMetadata)
 361                        .Select(x => x!.Variable)
 41362                        .ToList();
 363
 108364                    foreach (var variable in variables)
 14365                        yield return variable;
 366                }
 367                else
 368                {
 81369                    var variables = activityExecutionContext.Variables;
 370
 208371                    foreach (var variable in variables)
 28372                        yield return variable;
 373                }
 374
 110375                currentScope = currentScope.ParentContext;
 376            }
 377
 39378            if (context.TryGetWorkflowExecutionContext(out var workflowExecutionContext))
 379            {
 19380                if (workflowExecutionContext.Workflow.ResultVariable != null)
 12381                    yield return workflowExecutionContext.Workflow.ResultVariable;
 382            }
 39383        }
 384
 385        /// <summary>
 386        /// Returns the input value associated with the specified <see cref="InputDefinition"/> in the given <see cref="
 387        /// </summary>
 388        /// <typeparam name="T">The type of the input value.</typeparam>
 389        /// <param name="inputDefinition">The <see cref="InputDefinition"/> specifying the input to retrieve.</param>
 390        /// <returns>The input value associated with the specified <see cref="InputDefinition"/> in the <see cref="Expre
 391        public T? GetInput<T>(InputDefinition inputDefinition)
 392        {
 15393            return context.GetInput<T>(inputDefinition.Name);
 394        }
 395    }
 396
 397    private static JsonSerializerOptions GetSerializerOptions(ExpressionExecutionContext context)
 398    {
 19399        return context.GetRequiredService<IJsonSerializer>().GetOptions().CloneForValueConversion();
 400    }
 401
 402    extension(ExpressionExecutionContext context)
 403    {
 404        /// <summary>
 405        /// Returns the value of the specified input.
 406        /// </summary>
 407        /// <param name="name">The name of the input.</param>
 408        /// <typeparam name="T">The type of the input.</typeparam>
 409        /// <returns>The value of the specified input.</returns>
 410        public T? GetInput<T>(string name)
 411        {
 19412            var value = context.GetInput(name);
 19413            var serializerOptions = GetSerializerOptions(context);
 19414            var converterOptions = new ObjectConverterOptions(serializerOptions);
 19415            return value.ConvertTo<T>(converterOptions);
 416        }
 417
 418        /// <summary>
 419        /// Returns the value of the specified input.
 420        /// </summary>
 421        /// <param name="name">The name of the input.</param>
 422        /// <returns>The value of the specified input.</returns>
 423        public object? GetInput(string name)
 424        {
 19425            if (context.IsContainedWithinCompositeActivity())
 426            {
 427                // If there's a variable in the current scope with the specified name, return that.
 0428                var variable = context.GetVariable(name);
 429
 0430                if (variable != null)
 0431                    return variable.Get(context);
 432            }
 433
 434            // Otherwise, return the input.
 19435            var workflowExecutionContext = context.GetWorkflowExecutionContext();
 19436            var input = workflowExecutionContext.Input;
 19437            return input.TryGetValue(name, out var value) ? value : null;
 438        }
 439
 440        /// <summary>
 441        /// Returns the value of the specified output.
 442        /// </summary>
 443        /// <param name="activityIdOrName">The ID or name of the activity.</param>
 444        /// <param name="outputName">The name of the output.</param>
 445        /// <returns>The value of the specified output.</returns>
 446        /// <exception cref="InvalidOperationException">Thrown when the activity is not found.</exception>
 447        public object? GetOutput(string activityIdOrName, string? outputName)
 448        {
 0449            var workflowExecutionContext = context.GetWorkflowExecutionContext();
 0450            var activityExecutionContext = context.GetActivityExecutionContext();
 0451            var activity = activityExecutionContext.FindActivityByIdOrName(activityIdOrName);
 452
 0453            if (activity == null)
 0454                throw new InvalidOperationException("Activity not found.");
 455
 0456            var outputRegister = workflowExecutionContext.GetActivityOutputRegister();
 0457            var outputRecordCandidates = outputRegister.FindMany(activity.Id, outputName);
 0458            var containerIds = activityExecutionContext.GetAncestors().Select(x => x.Id).ToList();
 0459            var filteredOutputRecordCandidates = outputRecordCandidates.Where(x => containerIds.Contains(x.ContainerId))
 0460            var outputRecord = filteredOutputRecordCandidates.FirstOrDefault();
 0461            return outputRecord?.Value;
 462        }
 463
 464        /// <summary>
 465        /// Returns all activity outputs.
 466        /// </summary>
 467        public async IAsyncEnumerable<ActivityOutputs> GetActivityOutputs()
 468        {
 0469            if (!context.TryGetActivityExecutionContext(out var activityExecutionContext))
 0470                yield break;
 471
 0472            var useActivityName = activityExecutionContext.WorkflowExecutionContext.Workflow.CreatedWithModernTooling();
 0473            var activitiesWithOutputs = activityExecutionContext.GetActivitiesWithOutputs();
 474
 0475            if (useActivityName)
 476                activitiesWithOutputs = activitiesWithOutputs.Where(x => !string.IsNullOrWhiteSpace(x.Activity.Name));
 477
 0478            await foreach (var activityWithOutput in activitiesWithOutputs)
 479            {
 0480                var activity = activityWithOutput.Activity;
 0481                var activityDescriptor = activityWithOutput.ActivityDescriptor;
 0482                var activityIdentifier = useActivityName ? activity.Name! : activity.Id;
 0483                var activityIdPascalName = activityIdentifier.Pascalize();
 484
 0485                foreach (var output in activityDescriptor.Outputs)
 486                {
 0487                    var outputPascalName = output.Name.Pascalize();
 0488                    yield return new(activity.Id, activityIdPascalName, [
 0489                        outputPascalName
 0490                    ]);
 491                }
 0492            }
 0493        }
 494
 495        /// <summary>
 496        /// Returns a value indicating whether the current activity is inside a composite activity.
 497        /// </summary>
 498        public bool IsContainedWithinCompositeActivity()
 499        {
 38500            if (!context.TryGetActivityExecutionContext(out var activityExecutionContext))
 10501                return false;
 502
 503            // If the first workflow definition in the ancestor hierarchy and that workflow definition has a parent, the
 66504            var firstWorkflowContext = activityExecutionContext.GetAncestors().FirstOrDefault(x => x.Activity is Workflo
 505
 28506            return firstWorkflowContext?.ParentActivityExecutionContext != null;
 507        }
 508
 509        /// <summary>
 510        /// Returns the result of the activity that was executed before the current activity.
 511        /// </summary>
 512        public object? GetLastResult()
 513        {
 0514            var workflowExecutionContext = context.GetWorkflowExecutionContext();
 0515            return workflowExecutionContext.GetLastActivityResult();
 516        }
 517
 518        /// <summary>
 519        /// Returns all activity inputs.
 520        /// </summary>
 521        public IEnumerable<WorkflowInput> GetWorkflowInputs()
 522        {
 523            // Check if we are evaluating an expression during workflow execution.
 18524            if (context.TryGetWorkflowExecutionContext(out var workflowExecutionContext))
 525            {
 8526                var input = workflowExecutionContext.Input;
 527
 24528                foreach (var inputEntry in input)
 529                {
 4530                    var inputPascalName = inputEntry.Key.Pascalize();
 4531                    var inputValue = inputEntry.Value;
 4532                    yield return new(inputPascalName, inputValue);
 533                }
 534            }
 535            else
 536            {
 537                // We end up here when we are evaluating an expression during trigger indexing.
 538                // The scenario being that a workflow definition might have variables declared, that we want to be able 
 20539                foreach (var block in context.Memory.Blocks.Values)
 540                {
 0541                    if (block.Metadata is not VariableBlockMetadata variableBlockMetadata)
 542                        continue;
 543
 0544                    var variable = variableBlockMetadata.Variable;
 0545                    var variablePascalName = variable.Name.Pascalize();
 0546                    yield return new(variablePascalName, block.Value);
 547                }
 548            }
 18549        }
 550    }
 551
 552    private static object ConvertIEnumerableToArray(object? obj)
 553    {
 2554        if (obj == null)
 0555            return null!;
 556
 557        // If it's not an IEnumerable or it's a string or dictionary, return the original object.
 2558        if (obj is not IEnumerable enumerable || obj is string || obj is IDictionary)
 2559            return obj;
 560
 561        // If this is an async enumerable, return as-is.
 0562        if (obj.GetType().Name == "AsyncIListEnumerableAdapter`1")
 0563            return obj;
 564
 565        // Use LINQ to convert the IEnumerable to an array.
 566        // For projection operators like Select, the element type is the LAST generic argument
 567        // (e.g., ListSelectIterator<TSource, TResult> where TResult is the element type)
 0568        var elementType = obj.GetType().GetGenericArguments().LastOrDefault();
 569
 0570        if (elementType == null)
 0571            return obj;
 572
 0573        var toArrayMethod = typeof(Enumerable).GetMethod("ToArray")!.MakeGenericMethod(elementType);
 0574        return toArrayMethod.Invoke(null, [
 0575            enumerable
 0576        ])!;
 577    }
 578}

Methods/Properties

.cctor()
CreateActivityExecutionContextPropertiesFrom(Elsa.Workflows.WorkflowExecutionContext,System.Collections.Generic.IDictionary`2<System.String,System.Object>)
CreateTriggerIndexingPropertiesFrom(Elsa.Workflows.Activities.Workflow,System.Collections.Generic.IDictionary`2<System.String,System.Object>)
TryGetWorkflowExecutionContext(Elsa.Expressions.Models.ExpressionExecutionContext,Elsa.Workflows.WorkflowExecutionContext&)
GetWorkflowExecutionContext(Elsa.Expressions.Models.ExpressionExecutionContext)
GetActivityExecutionContext(Elsa.Expressions.Models.ExpressionExecutionContext)
TryGetActivityExecutionContext(Elsa.Expressions.Models.ExpressionExecutionContext,Elsa.Workflows.ActivityExecutionContext&)
GetActivity(Elsa.Expressions.Models.ExpressionExecutionContext)
Get(Elsa.Expressions.Models.ExpressionExecutionContext,Elsa.Workflows.Models.Input`1<T>)
Get(Elsa.Expressions.Models.ExpressionExecutionContext,Elsa.Workflows.Models.Output)
Get(Elsa.Expressions.Models.ExpressionExecutionContext,Elsa.Workflows.Models.Output)
GetVariable(Elsa.Expressions.Models.ExpressionExecutionContext,System.String)
GetVariable(Elsa.Expressions.Models.ExpressionExecutionContext,System.String,System.Boolean)
GetVariableBlock(Elsa.Expressions.Models.ExpressionExecutionContext,System.String,System.Boolean)
CreateVariable(Elsa.Expressions.Models.ExpressionExecutionContext,System.String,T,System.Type,System.Action`1<Elsa.Expressions.Models.MemoryBlock>)
GetVariableContainerContext(Elsa.Expressions.Models.ExpressionExecutionContext)
SetVariable(Elsa.Expressions.Models.ExpressionExecutionContext,System.String,T,System.Action`1<Elsa.Expressions.Models.MemoryBlock>)
Set(Elsa.Expressions.Models.ExpressionExecutionContext,Elsa.Workflows.Models.Output,System.Object,System.Action`1<Elsa.Expressions.Models.MemoryBlock>)
SetBoundValue(Elsa.Expressions.Models.ExpressionExecutionContext,Elsa.Workflows.Models.Output,System.Object)
ReadAndFlattenMemoryBlocks(Elsa.Expressions.Models.ExpressionExecutionContext)
FlattenMemoryBlocks(Elsa.Expressions.Models.ExpressionExecutionContext)
FindContextContainingBlock(Elsa.Expressions.Models.ExpressionExecutionContext,System.String)
FindParent(Elsa.Expressions.Models.ExpressionExecutionContext,System.Func`2<Elsa.Expressions.Models.ExpressionExecutionContext,System.Boolean>)
GetVariableInScope(Elsa.Expressions.Models.ExpressionExecutionContext,System.String)
GetVariableNamesInScope(Elsa.Expressions.Models.ExpressionExecutionContext)
GetVariablesInScope(Elsa.Expressions.Models.ExpressionExecutionContext)
SetVariableInScope(Elsa.Expressions.Models.ExpressionExecutionContext,System.String,System.Object)
EnumerateVariablesInScope()
GetInput(Elsa.Expressions.Models.ExpressionExecutionContext,Elsa.Workflows.Models.InputDefinition)
GetSerializerOptions(Elsa.Expressions.Models.ExpressionExecutionContext)
GetInput(Elsa.Expressions.Models.ExpressionExecutionContext,System.String)
GetInput(Elsa.Expressions.Models.ExpressionExecutionContext,System.String)
GetOutput(Elsa.Expressions.Models.ExpressionExecutionContext,System.String,System.String)
GetActivityOutputs()
IsContainedWithinCompositeActivity(Elsa.Expressions.Models.ExpressionExecutionContext)
GetLastResult(Elsa.Expressions.Models.ExpressionExecutionContext)
GetWorkflowInputs()
ConvertIEnumerableToArray(System.Object)