< Summary

Information
Class: Elsa.Expressions.CSharp.Handlers.GenerateWorkflowVariableAccessors
Assembly: Elsa.Expressions.CSharp
File(s): /home/runner/work/elsa-core/elsa-core/src/modules/Elsa.Expressions.CSharp/Handlers/GenerateWorkflowVariableAccessors.cs
Line coverage
3%
Covered lines: 1
Uncovered lines: 28
Coverable lines: 29
Total lines: 65
Line coverage: 3.4%
Branch coverage
0%
Covered branches: 0
Total branches: 8
Branch coverage: 0%
Method coverage

Feature is only available for sponsors

Upgrade to PRO version

Metrics

MethodBranch coverage Crap Score Cyclomatic complexity Line coverage
.ctor(...)100%11100%
HandleAsync(...)0%7280%

File(s)

/home/runner/work/elsa-core/elsa-core/src/modules/Elsa.Expressions.CSharp/Handlers/GenerateWorkflowVariableAccessors.cs

#LineLine coverage
 1using System.Dynamic;
 2using System.Text;
 3using Elsa.Expressions.CSharp.Extensions;
 4using Elsa.Expressions.CSharp.Notifications;
 5using Elsa.Expressions.CSharp.Options;
 6using Elsa.Expressions.Models;
 7using Elsa.Extensions;
 8using Elsa.Mediator.Contracts;
 9using Humanizer;
 10using JetBrains.Annotations;
 11using Microsoft.Extensions.Options;
 12
 13namespace Elsa.Expressions.CSharp.Handlers;
 14
 15/// <summary>
 16/// Configures the C# evaluator with methods to access workflow variables.
 17/// </summary>
 18[UsedImplicitly]
 39419public class GenerateWorkflowVariableAccessors(IOptions<CSharpOptions> options) : INotificationHandler<EvaluatingCSharp>
 20{
 21    /// <inheritdoc />
 22    public Task HandleAsync(EvaluatingCSharp notification, CancellationToken cancellationToken)
 23    {
 024        var expressionExecutionContext = notification.Context;
 025        var variables = expressionExecutionContext.GetVariablesInScope().ToList();
 26
 027        var sb = new StringBuilder();
 028        sb.AppendLine("public partial class WorkflowVariablesProxy {");
 029        sb.AppendLine("\tpublic WorkflowVariablesProxy(ExecutionContextProxy executionContext) => ExecutionContext = exe
 030        sb.AppendLine("\tpublic ExecutionContextProxy ExecutionContext { get; }");
 031        sb.AppendLine();
 032        sb.AppendLine("\tpublic T? Get<T>(string name) => ExecutionContext.GetVariable<T>(name);");
 033        sb.AppendLine("\tpublic object? Get(string name) => ExecutionContext.GetVariable(name);");
 034        sb.AppendLine("\tpublic void Set(string name, object? value) => ExecutionContext.SetVariable(name, value);");
 035        sb.AppendLine();
 36
 037        if (!options.Value.DisableWrappers)
 38        {
 039            foreach (var variable in variables.Where(x => x.Name.IsValidVariableName()))
 40            {
 041                var variableName = variable.Name.Pascalize();
 042                var variableType = variable.GetVariableType();
 43
 44                // Check if the variable type is ExpandoObject
 045                bool isExpandoObject = variableType == typeof(ExpandoObject);
 46
 47                // Use dynamic type for ExpandoObject to enable dot notation but keep the original type for retrieval
 048                var displayTypeName = isExpandoObject ? "dynamic" : variableType.GetFriendlyTypeName(Brackets.Angle);
 049                var retrieveTypeName = isExpandoObject ? "ExpandoObject" : displayTypeName;
 50
 051                sb.AppendLine($"\tpublic {displayTypeName} {variableName}");
 052                sb.AppendLine("\t{");
 053                sb.AppendLine($"\t\tget => Get<{retrieveTypeName}>(\"{variableName}\");");
 054                sb.AppendLine($"\t\tset => Set(\"{variableName}\", value);");
 055                sb.AppendLine("\t}");
 56            }
 57        }
 58
 059        sb.AppendLine("}");
 060        sb.AppendLine("var Variables = new WorkflowVariablesProxy(ExecutionContext);"); // Obsolete; use Variable instea
 061        sb.AppendLine("var Variable = Variables;");
 062        notification.AppendScript(sb.ToString());
 063        return Task.CompletedTask;
 64    }
 65}