2020-10-22 13:59:59 +00:00
using System ;
2019-11-12 17:47:44 +00:00
using System.Linq ;
using System.Reflection ;
using System.Threading ;
using System.Threading.Tasks ;
using Elsa.Attributes ;
2019-11-17 19:43:16 +00:00
using Elsa.Expressions ;
2019-11-12 17:47:44 +00:00
using Elsa.Results ;
using Elsa.Services ;
using Elsa.Services.Models ;
2019-11-17 19:43:16 +00:00
using Microsoft.Extensions.DependencyInjection ;
2019-11-12 17:47:44 +00:00
namespace Elsa.Activities.Reflection.Activities
{
/// <summary>
2019-11-17 19:43:16 +00:00
/// Execute a method by reflection.
2019-11-12 17:47:44 +00:00
/// </summary>
[ ActivityDefinition (
Category = "Reflection" ,
2019-11-17 19:43:16 +00:00
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
{
2019-11-17 19:43:16 +00:00
[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
{
2019-11-17 19:43:16 +00:00
get = > GetState < WorkflowExpression < object [ ] > > ( ) ;
set = > SetState ( value ) ;
2019-11-12 17:47:44 +00:00
}
2019-11-17 19:43:16 +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
{
2019-11-17 19:43:16 +00:00
get = > GetState < string > ( ) ;
set = > SetState ( value ) ;
2019-11-12 17:47:44 +00:00
}
2019-11-17 19:43:16 +00:00
[ActivityProperty(Hint = "The name of the method name to execute.")]
2019-11-12 17:47:44 +00:00
public string MethodName
{
2019-11-17 19:43:16 +00:00
get = > GetState < string > ( ) ;
set = > SetState ( value ) ;
2019-11-12 17:47:44 +00:00
}
2019-11-17 19:43:16 +00:00
protected override async Task < ActivityExecutionResult > OnExecuteAsync ( WorkflowExecutionContext context , CancellationToken cancellationToken )
2019-11-12 17:47:44 +00:00
{
2019-11-17 19:43:16 +00:00
var type = System . Type . GetType ( TypeName ) ;
2019-11-12 17:47:44 +00:00
2019-11-17 19:43:16 +00:00
if ( type = = null )
return Fault ( $"Type {TypeName} not found." ) ;
2019-11-12 17:47:44 +00:00
2020-10-22 13:59:59 +00:00
var inputValues = await context . EvaluateAsync ( Arguments , cancellationToken ) ? ? Array . Empty < object > ( ) ;
2019-11-12 17:47:44 +00:00
2019-11-17 19:43:16 +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
2019-11-17 19:43:16 +00:00
if ( method = = null )
return Fault ( $"Type {TypeName} does not have a method called {MethodName}." ) ;
2019-11-12 17:47:44 +00:00
2019-11-17 19:43:16 +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
2019-11-17 19:43:16 +00:00
Output . SetVariable ( "Result" , result ) ;
2019-11-12 17:47:44 +00:00
return Outcome ( OutcomeNames . Done ) ;
}
}
}