Merge pull request #146 from Andale-biz/Feature_Reflection_Activities
This commit is contained in:
commit
3ea596cdba
|
|
@ -0,0 +1,117 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Reflection;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using Elsa.Attributes;
|
||||
using Elsa.Results;
|
||||
using Elsa.Services;
|
||||
using Elsa.Services.Models;
|
||||
|
||||
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
|
||||
{
|
||||
|
||||
public ExecuteMethod(IWorkflowExpressionEvaluator evaluator)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
|
||||
[ActivityProperty(Hint = "The variables to use as parameters, seperated by comma in order of method call.")]
|
||||
public string InputVariableNames
|
||||
{
|
||||
get => GetState<string>(null, "InputVariableNames");
|
||||
set => SetState(value, "InputVariableNames");
|
||||
}
|
||||
|
||||
[ActivityProperty(Hint = "The name of the variable to store the returned value into.")]
|
||||
public string OutputVariableName
|
||||
{
|
||||
get => GetState<string>(null, "OutputVariableName");
|
||||
set => SetState(value, "OutputVariableName");
|
||||
}
|
||||
|
||||
[ActivityProperty(Hint = "Assembly name (fullname or filename) to load")]
|
||||
public string AssemblyName
|
||||
{
|
||||
get => GetState<string>(null, "AssemblyName");
|
||||
set => SetState(value, "AssemblyName");
|
||||
}
|
||||
|
||||
[ActivityProperty(Hint = "Class name to start or lookup")]
|
||||
public string ClassName
|
||||
{
|
||||
get => GetState<string>(null, "ClassName");
|
||||
set => SetState(value, "ClassName");
|
||||
}
|
||||
|
||||
[ActivityProperty(Hint = "Class is a static class?")]
|
||||
public bool IsStaticClass
|
||||
{
|
||||
get => GetState<bool>(null, "IsStaticClass");
|
||||
set => SetState(value, "IsStaticClass");
|
||||
}
|
||||
|
||||
[ActivityProperty(Hint = "Method name to execute")]
|
||||
public string MethodName
|
||||
{
|
||||
get => GetState<string>(null, "MethodName");
|
||||
set => SetState(value, "MethodName");
|
||||
}
|
||||
|
||||
protected override async Task<ActivityExecutionResult> OnExecuteAsync(
|
||||
WorkflowExecutionContext context,
|
||||
CancellationToken cancellationToken)
|
||||
{
|
||||
await Task.Delay(1);
|
||||
var inputValues = InputVariableNames.Split(',').Select(s => context.GetVariable(s)).ToArray();
|
||||
return Execute(context, inputValues);
|
||||
}
|
||||
|
||||
protected override ActivityExecutionResult OnResume(WorkflowExecutionContext context)
|
||||
{
|
||||
var inputValues = InputVariableNames.Split(',').Select(s => context.GetVariable(s)).ToArray();
|
||||
return Execute(context, inputValues);
|
||||
}
|
||||
|
||||
private ActivityExecutionResult Execute(WorkflowExecutionContext workflowContext, object[] receivedInputValues)
|
||||
{
|
||||
string path = Directory.EnumerateFiles(AppDomain.CurrentDomain.BaseDirectory, AssemblyName, SearchOption.AllDirectories).FirstOrDefault();
|
||||
Assembly assembly = Assembly.LoadFrom(path);
|
||||
object receivedOutput = null;
|
||||
var classType = assembly.DefinedTypes.Where(t => t.Name == ClassName).FirstOrDefault();
|
||||
|
||||
if (IsStaticClass)
|
||||
{
|
||||
var staticMethod = classType.DeclaredMethods.Where(m => m.Name == MethodName).FirstOrDefault();
|
||||
receivedOutput = staticMethod.Invoke(null, receivedInputValues);
|
||||
}
|
||||
else
|
||||
{
|
||||
var instancedClass = Activator.CreateInstance(classType);
|
||||
var instanceMethod = instancedClass.GetType().GetMethod(MethodName);
|
||||
receivedOutput = instanceMethod.Invoke(instancedClass, receivedInputValues);
|
||||
}
|
||||
|
||||
workflowContext.CurrentScope.SetVariable(OutputVariableName, receivedOutput);
|
||||
|
||||
workflowContext.SetLastResult(receivedOutput);
|
||||
|
||||
|
||||
return Outcome(OutcomeNames.Done);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,81 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Reflection;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using Elsa.Attributes;
|
||||
using Elsa.Results;
|
||||
using Elsa.Services;
|
||||
using Elsa.Services.Models;
|
||||
|
||||
namespace Elsa.Activities.Reflection.Activities
|
||||
{
|
||||
/// <summary>
|
||||
/// Execute a Method by reflection.
|
||||
/// </summary>
|
||||
[ActivityDefinition(
|
||||
Category = "Reflection",
|
||||
Description = "Split object in multiple parts to process seperately.",
|
||||
RuntimeDescription = "Split object in multiple parts to process seperately.",
|
||||
Outcomes = "x => x.state.properties.map(c => c.toString())"
|
||||
)]
|
||||
public class SplitObject : Activity
|
||||
{
|
||||
public SplitObject()
|
||||
{
|
||||
Properties = new List<string>();
|
||||
}
|
||||
|
||||
[ActivityProperty(Hint = "The variable with the object to split")]
|
||||
public string InputVariableName
|
||||
{
|
||||
get => GetState<string>(null, "InputVariableName");
|
||||
set => SetState(value, "InputVariableName");
|
||||
}
|
||||
|
||||
[ActivityProperty(Hint = "A comma-separated list of possible outcomes for the split parts. These are the property names of the splitted object.")]
|
||||
public IReadOnlyCollection<string> Properties
|
||||
{
|
||||
get => GetState<IReadOnlyCollection<string>>();
|
||||
set => SetState(value);
|
||||
}
|
||||
|
||||
protected override async Task<ActivityExecutionResult> OnExecuteAsync(
|
||||
WorkflowExecutionContext context,
|
||||
CancellationToken cancellationToken)
|
||||
{
|
||||
object splitObject = null;
|
||||
if (string.IsNullOrEmpty(InputVariableName))
|
||||
{
|
||||
splitObject = context.GetVariable(InputVariableName);
|
||||
}
|
||||
|
||||
if (splitObject != null)
|
||||
{
|
||||
foreach (var Property in Properties)
|
||||
{
|
||||
object PropValue = FollowPropertyPath(splitObject, Property);
|
||||
context.SetVariable(Property, PropValue);
|
||||
}
|
||||
}
|
||||
|
||||
return Outcomes(Properties.ToList());
|
||||
}
|
||||
|
||||
protected object FollowPropertyPath(object value, string path)
|
||||
{
|
||||
Type currentType = value.GetType();
|
||||
|
||||
foreach (string propertyName in path.Split('.'))
|
||||
{
|
||||
PropertyInfo property = currentType.GetProperty(propertyName);
|
||||
value = property.GetValue(value, null);
|
||||
currentType = property.PropertyType;
|
||||
}
|
||||
return value;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,26 @@
|
|||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<PropertyGroup>
|
||||
<TargetFramework>netstandard2.0</TargetFramework>
|
||||
<PackageVersion>1.0.0</PackageVersion>
|
||||
<LangVersion>latest</LangVersion>
|
||||
<Authors>Elsa Contributors</Authors>
|
||||
<Description>
|
||||
Elsa is a set of workflow libraries and tools that enable super-fast workflowing capabilities in any .NET Core application.
|
||||
This package provides the following Reflection activities:
|
||||
|
||||
* ExecuteFunction
|
||||
|
||||
</Description>
|
||||
<Copyright>2019</Copyright>
|
||||
<PackageProjectUrl>https://github.com/elsa-workflows/elsa-core</PackageProjectUrl>
|
||||
<RepositoryUrl>https://github.com/elsa-workflows/elsa-core</RepositoryUrl>
|
||||
<RepositoryType>GitHub</RepositoryType>
|
||||
<PackageTags>elsa, workflows</PackageTags>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\..\core\Elsa.Core\Elsa.Core.csproj" />
|
||||
</ItemGroup>
|
||||
|
||||
</Project>
|
||||
|
|
@ -0,0 +1,15 @@
|
|||
using Elsa.Activities.Reflection.Activities;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
|
||||
namespace Elsa.Activities.Reflection.Extensions
|
||||
{
|
||||
public static class ServiceCollectionExtensions
|
||||
{
|
||||
public static IServiceCollection AddReflectionActivities(this IServiceCollection services)
|
||||
{
|
||||
return services
|
||||
.AddActivity<ExecuteMethod>()
|
||||
.AddActivity<SplitObject>();
|
||||
}
|
||||
}
|
||||
}
|
||||
Loading…
Reference in a new issue