elsa-core/src/activities/Elsa.Activities.Reflection/Activities/ExecuteFunction.cs
Sviataslau Hankovich cfcbc3d762
Code cleanup (#413)
2020-10-22 15:59:59 +02:00

72 lines
2.7 KiB
C#

using System;
using System.Linq;
using System.Reflection;
using System.Threading;
using System.Threading.Tasks;
using Elsa.Attributes;
using Elsa.Expressions;
using Elsa.Results;
using Elsa.Services;
using Elsa.Services.Models;
using Microsoft.Extensions.DependencyInjection;
namespace Elsa.Activities.Reflection.Activities
{
/// <summary>
/// Execute a method by reflection.
/// </summary>
[ActivityDefinition(
Category = "Reflection",
Description = "Execute a method by reflection.",
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
{
get => GetState<WorkflowExpression<object[]>>();
set => SetState(value);
}
[ActivityProperty(Hint = "The assembly-qualified type name containing the method to execute.")]
public string TypeName
{
get => GetState<string>();
set => SetState(value);
}
[ActivityProperty(Hint = "The name of the method name to execute.")]
public string MethodName
{
get => GetState<string>();
set => SetState(value);
}
protected override async Task<ActivityExecutionResult> OnExecuteAsync(WorkflowExecutionContext context, CancellationToken cancellationToken)
{
var type = System.Type.GetType(TypeName);
if (type == null)
return Fault($"Type {TypeName} not found.");
var inputValues = await context.EvaluateAsync(Arguments, cancellationToken) ?? Array.Empty<object>();
var method = type
.GetMethods(BindingFlags.Static | BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic)
.Where(x => x.GetParameters().Length == inputValues.Length)
.FirstOrDefault(x => x.Name == MethodName);
if (method == null)
return Fault($"Type {TypeName} does not have a method called {MethodName}.");
var instance = method.IsStatic ? default : ActivatorUtilities.GetServiceOrCreateInstance(context.ServiceProvider, type);
var result = method.Invoke(instance, inputValues);
Output.SetVariable("Result", result);
return Outcome(OutcomeNames.Done);
}
}
}