elsa-core/src/activities/Elsa.Activities.Reflection/Activities/ExecuteFunction.cs

71 lines
2.7 KiB
C#
Raw Normal View History

2019-11-12 17:47:44 +00:00
using System.Linq;
using System.Reflection;
using System.Threading;
using System.Threading.Tasks;
using Elsa.Attributes;
using Elsa.Expressions;
2019-11-12 17:47:44 +00:00
using Elsa.Results;
using Elsa.Services;
using Elsa.Services.Models;
using Microsoft.Extensions.DependencyInjection;
2019-11-12 17:47:44 +00:00
namespace Elsa.Activities.Reflection.Activities
{
/// <summary>
/// Execute a method by reflection.
2019-11-12 17:47:44 +00:00
/// </summary>
[ActivityDefinition(
Category = "Reflection",
Description = "Execute a method by reflection.",
2019-11-12 17:47:44 +00:00
RuntimeDescription = "a => !!a.state.variableName ? `Execute a Method by reflection and store the result into <strong>${ a.state.variableName }</strong>.` : 'Execute a Method by reflection.'",
Outcomes = new[] { OutcomeNames.Done }
)]
public class ExecuteMethod : Activity
{
[ActivityProperty(Hint = "An expression that returns an array of arguments to the method. Leave empty if the method does not accept any arguments.")]
public WorkflowExpression<object[]> Arguments
2019-11-12 17:47:44 +00:00
{
get => GetState<WorkflowExpression<object[]>>();
set => SetState(value);
2019-11-12 17:47:44 +00:00
}
[ActivityProperty(Hint = "The assembly-qualified type name containing the method to execute.")]
public string TypeName
2019-11-12 17:47:44 +00:00
{
get => GetState<string>();
set => SetState(value);
2019-11-12 17:47:44 +00:00
}
[ActivityProperty(Hint = "The name of the method name to execute.")]
2019-11-12 17:47:44 +00:00
public string MethodName
{
get => GetState<string>();
set => SetState(value);
2019-11-12 17:47:44 +00:00
}
protected override async Task<ActivityExecutionResult> OnExecuteAsync(WorkflowExecutionContext context, CancellationToken cancellationToken)
2019-11-12 17:47:44 +00:00
{
var type = System.Type.GetType(TypeName);
2019-11-12 17:47:44 +00:00
if (type == null)
return Fault($"Type {TypeName} not found.");
2019-11-12 17:47:44 +00:00
var inputValues = await context.EvaluateAsync(Arguments, cancellationToken) ?? new object[0];
2019-11-12 17:47:44 +00:00
var method = type
.GetMethods(BindingFlags.Static | BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic)
.Where(x => x.GetParameters().Length == inputValues.Length)
.FirstOrDefault(x => x.Name == MethodName);
2019-11-12 17:47:44 +00:00
if (method == null)
return Fault($"Type {TypeName} does not have a method called {MethodName}.");
2019-11-12 17:47:44 +00:00
var instance = method.IsStatic ? default : ActivatorUtilities.GetServiceOrCreateInstance(context.ServiceProvider, type);
var result = method.Invoke(instance, inputValues);
2019-11-12 17:47:44 +00:00
Output.SetVariable("Result", result);
2019-11-12 17:47:44 +00:00
return Outcome(OutcomeNames.Done);
}
}
}