Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
55 changes: 48 additions & 7 deletions src/WorkflowCore.DSL/Services/DefinitionLoader.cs
Original file line number Diff line number Diff line change
Expand Up @@ -318,12 +318,14 @@ private void AttachDirectlyOutput(KeyValuePair<string, string> output, WorkflowS
propertyInfo = dataType.GetProperty("Item");
targetProperty = Expression.Property(dataParameter, propertyInfo, Expression.Constant(output.Key));

var compiledSourceExpr = sourceExpr.Compile();

Action<IStepBody, object> acn = (pStep, pData) =>
{
object resolvedValue;
try
{
resolvedValue = sourceExpr.Compile().DynamicInvoke(pStep);
resolvedValue = compiledSourceExpr.DynamicInvoke(pStep);
}
catch (TargetInvocationException ex)
{
Expand Down Expand Up @@ -377,13 +379,16 @@ private void AttachNestedOutput(KeyValuePair<string, string> output, WorkflowSte
}
propertyInfo = ((PropertyInfo)memberExpression.Member).PropertyType.GetProperty("Item");

var targetExpr = Expression.Lambda(memberExpression, dataParameter);
var compiledTargetExpr = targetExpr.Compile();
var compiledSourceExpr = sourceExpr.Compile();

Action<IStepBody, object> acn = (pStep, pData) =>
{
var targetExpr = Expression.Lambda(memberExpression, dataParameter);
object data;
try
{
data = targetExpr.Compile().DynamicInvoke(pData);
data = compiledTargetExpr.DynamicInvoke(pData);
}
catch (TargetInvocationException ex)
{
Expand All @@ -392,7 +397,7 @@ private void AttachNestedOutput(KeyValuePair<string, string> output, WorkflowSte
object resolvedValue;
try
{
resolvedValue = sourceExpr.Compile().DynamicInvoke(pStep);
resolvedValue = compiledSourceExpr.DynamicInvoke(pStep);
}
catch (TargetInvocationException ex)
{
Expand Down Expand Up @@ -470,12 +475,14 @@ private static Action<IStepBody, object, IStepExecutionContext> BuildScalarInput
throw new WorkflowDefinitionLoadException($"Error parsing input expression '{expr}' for property '{input.Key}': {ex.Message}", ex);
}

var compiledExpr = sourceExpr.Compile();

void acn(IStepBody pStep, object pData, IStepExecutionContext pContext)
{
object resolvedValue;
try
{
resolvedValue = sourceExpr.Compile().DynamicInvoke(pData, pContext, Environment.GetEnvironmentVariables());
resolvedValue = compiledExpr.DynamicInvoke(pData, pContext, Environment.GetEnvironmentVariables());
}
catch (TargetInvocationException ex)
{
Expand Down Expand Up @@ -505,6 +512,40 @@ void acn(IStepBody pStep, object pData, IStepExecutionContext pContext)

private static Action<IStepBody, object, IStepExecutionContext> BuildObjectInputAction(KeyValuePair<string, object> input, ParameterExpression dataParameter, ParameterExpression contextParameter, ParameterExpression environmentVarsParameter, PropertyInfo stepProperty)
{
// Pre-compile all @-prefixed property expressions at definition load time
var compiledExpressions = new Dictionary<string, Delegate>();
var templateObj = JObject.FromObject(input.Value);
var scanStack = new Stack<JObject>();
scanStack.Push(templateObj);

while (scanStack.Count > 0)
{
var subobj = scanStack.Pop();
foreach (var prop in subobj.Properties())
{
if (prop.Name.StartsWith("@"))
{
var exprText = prop.Value.ToString();
if (!compiledExpressions.ContainsKey(exprText))
{
LambdaExpression sourceExpr;
try
{
sourceExpr = DynamicExpressionParser.ParseLambda(ParsingConfig, false, new[] { dataParameter, contextParameter, environmentVarsParameter }, typeof(object), TransformExpression(exprText));
}
catch (Exception ex) when (ex is System.Linq.Dynamic.Core.Exceptions.ParseException || ex is InvalidOperationException)
{
throw new WorkflowDefinitionLoadException($"Error parsing input expression '{exprText}': {ex.Message}", ex);
}
compiledExpressions[exprText] = sourceExpr.Compile();
}
}
}

foreach (var child in subobj.Children<JObject>())
scanStack.Push(child);
}

void acn(IStepBody pStep, object pData, IStepExecutionContext pContext)
{
var stack = new Stack<JObject>();
Expand All @@ -518,11 +559,11 @@ void acn(IStepBody pStep, object pData, IStepExecutionContext pContext)
{
if (prop.Name.StartsWith("@"))
{
var sourceExpr = DynamicExpressionParser.ParseLambda(ParsingConfig, false, new[] { dataParameter, contextParameter, environmentVarsParameter }, typeof(object), TransformExpression(prop.Value.ToString()));
var exprText = prop.Value.ToString();
object resolvedValue;
try
{
resolvedValue = sourceExpr.Compile().DynamicInvoke(pData, pContext, Environment.GetEnvironmentVariables());
resolvedValue = compiledExpressions[exprText].DynamicInvoke(pData, pContext, Environment.GetEnvironmentVariables());
}
catch (TargetInvocationException ex)
{
Expand Down
20 changes: 11 additions & 9 deletions src/WorkflowCore/Models/MemberMapParameter.cs
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ public class MemberMapParameter : IStepParameter
{
private readonly LambdaExpression _source;
private readonly LambdaExpression _target;
private readonly Delegate _compiledSource;

public MemberMapParameter(LambdaExpression source, LambdaExpression target)
{
Expand All @@ -17,44 +18,45 @@ public MemberMapParameter(LambdaExpression source, LambdaExpression target)

_source = source;
_target = target;
_compiledSource = source.Compile();
}

private void Assign(object sourceObject, LambdaExpression sourceExpr, object targetObject, LambdaExpression targetExpr, IStepExecutionContext context)
private void Assign(object sourceObject, object targetObject, IStepExecutionContext context)
{
object resolvedValue = null;

switch (sourceExpr.Parameters.Count)
switch (_source.Parameters.Count)
{
case 1:
resolvedValue = sourceExpr.Compile().DynamicInvoke(sourceObject);
resolvedValue = _compiledSource.DynamicInvoke(sourceObject);
break;
case 2:
resolvedValue = sourceExpr.Compile().DynamicInvoke(sourceObject, context);
resolvedValue = _compiledSource.DynamicInvoke(sourceObject, context);
break;
default:
throw new ArgumentException();
}

if (resolvedValue == null)
{
var defaultAssign = Expression.Lambda(Expression.Assign(targetExpr.Body, Expression.Default(targetExpr.ReturnType)), targetExpr.Parameters.Single());
var defaultAssign = Expression.Lambda(Expression.Assign(_target.Body, Expression.Default(_target.ReturnType)), _target.Parameters.Single());
defaultAssign.Compile().DynamicInvoke(targetObject);
return;
}

var valueExpr = Expression.Convert(Expression.Constant(resolvedValue), targetExpr.ReturnType);
var assign = Expression.Lambda(Expression.Assign(targetExpr.Body, valueExpr), targetExpr.Parameters.Single());
var valueExpr = Expression.Convert(Expression.Constant(resolvedValue), _target.ReturnType);
var assign = Expression.Lambda(Expression.Assign(_target.Body, valueExpr), _target.Parameters.Single());
assign.Compile().DynamicInvoke(targetObject);
}

public void AssignInput(object data, IStepBody body, IStepExecutionContext context)
{
Assign(data, _source, body, _target, context);
Assign(data, body, context);
}

public void AssignOutput(object data, IStepBody body, IStepExecutionContext context)
{
Assign(body, _source, data, _target, context);
Assign(body, data, context);
}
}
}
2 changes: 1 addition & 1 deletion test/Directory.Build.props
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
<Project>
<PropertyGroup>
<TargetFrameworks>net6.0;net8.0</TargetFrameworks>
<TargetFrameworks>net6.0;net8.0;net10.0</TargetFrameworks>
<LangVersion>latest</LangVersion>
<IsPackable>false</IsPackable>
</PropertyGroup>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
<GenerateAssemblyConfigurationAttribute>false</GenerateAssemblyConfigurationAttribute>
<GenerateAssemblyCompanyAttribute>false</GenerateAssemblyCompanyAttribute>
<GenerateAssemblyProductAttribute>false</GenerateAssemblyProductAttribute>
<TargetFrameworks>net6.0</TargetFrameworks>
<TargetFrameworks>net6.0;net8.0;net10.0</TargetFrameworks>
</PropertyGroup>

<ItemGroup>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
<GenerateAssemblyConfigurationAttribute>false</GenerateAssemblyConfigurationAttribute>
<GenerateAssemblyCompanyAttribute>false</GenerateAssemblyCompanyAttribute>
<GenerateAssemblyProductAttribute>false</GenerateAssemblyProductAttribute>
<TargetFrameworks>net6.0</TargetFrameworks>
<TargetFrameworks>net6.0;net8.0;net10.0</TargetFrameworks>
</PropertyGroup>

<ItemGroup>
Expand Down