You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
113 lines
4.4 KiB
113 lines
4.4 KiB
using Elsa.Expressions.Helpers;
|
|
using Elsa.Extensions;
|
|
using Elsa.Workflows;
|
|
using Elsa.Workflows.Memory;
|
|
using Elsa.Workflows.Models;
|
|
using Humanizer;
|
|
using System.Text.Json;
|
|
|
|
namespace LY.MicroService.WorkflowManagement.Next;
|
|
|
|
public class AbpActivityFactory : IActivityFactory
|
|
{
|
|
public IActivity Create(Type type, ActivityConstructorContext context)
|
|
{
|
|
// Backwards compatibility for older JSON schemas.
|
|
var canStartWorkflow = GetBoolean(context.Element, "canStartWorkflow");
|
|
var runAsynchronously = GetBoolean(context.Element, "runAsynchronously");
|
|
var activityElement = context.Element;
|
|
var activityDescriptor = context.ActivityDescriptor;
|
|
var activity = (IActivity)context.Element.Deserialize(type, context.SerializerOptions)!;
|
|
var composite = activity as IComposite;
|
|
|
|
composite?.Setup();
|
|
|
|
// TODO: 反序列化未创建默认值?
|
|
if (activityDescriptor != null)
|
|
{
|
|
ReadSyntheticInputs(activityDescriptor, activity, activityElement, context.SerializerOptions);
|
|
ReadSyntheticOutputs(activityDescriptor, activity, activityElement);
|
|
}
|
|
|
|
activity.SetCanStartWorkflow(canStartWorkflow);
|
|
activity.SetRunAsynchronously(runAsynchronously);
|
|
|
|
return activity;
|
|
}
|
|
|
|
private void ReadSyntheticInputs(ActivityDescriptor activityDescriptor, IActivity activity, JsonElement activityRoot, JsonSerializerOptions options)
|
|
{
|
|
foreach (var inputDescriptor in activityDescriptor.Inputs.Where(x => x.IsSynthetic))
|
|
{
|
|
var inputName = inputDescriptor.Name;
|
|
var propertyName = inputName.Camelize();
|
|
var nakedType = inputDescriptor.Type;
|
|
var wrappedType = typeof(Input<>).MakeGenericType(nakedType);
|
|
|
|
if (!activityRoot.TryGetProperty(propertyName, out var propertyElement) || propertyElement.ValueKind == JsonValueKind.Null || propertyElement.ValueKind == JsonValueKind.Undefined)
|
|
continue;
|
|
|
|
var isWrapped = propertyElement.ValueKind == JsonValueKind.Object && propertyElement.GetProperty("typeName").ValueKind != JsonValueKind.Undefined;
|
|
|
|
if (isWrapped)
|
|
{
|
|
var json = propertyElement.ToString();
|
|
var inputValue = JsonSerializer.Deserialize(json, wrappedType, options);
|
|
|
|
activity.SyntheticProperties[inputName] = inputValue!;
|
|
}
|
|
else
|
|
{
|
|
activity.SyntheticProperties[inputName] = propertyElement.ConvertTo(inputDescriptor.Type)!;
|
|
}
|
|
}
|
|
}
|
|
|
|
private void ReadSyntheticOutputs(ActivityDescriptor activityDescriptor, IActivity activity, JsonElement activityRoot)
|
|
{
|
|
foreach (var outputDescriptor in activityDescriptor.Outputs.Where(x => x.IsSynthetic))
|
|
{
|
|
var outputName = outputDescriptor.Name;
|
|
var propertyName = outputName.Camelize();
|
|
var nakedType = outputDescriptor.Type;
|
|
var wrappedType = typeof(Output<>).MakeGenericType(nakedType);
|
|
|
|
if (!activityRoot.TryGetProperty(propertyName, out var propertyElement) || propertyElement.ValueKind == JsonValueKind.Null || propertyElement.ValueKind == JsonValueKind.Undefined)
|
|
continue;
|
|
|
|
var memoryReferenceElement = propertyElement.GetProperty("memoryReference");
|
|
|
|
if (!memoryReferenceElement.TryGetProperty("id", out var memoryReferenceIdElement))
|
|
continue;
|
|
|
|
var variable = new Variable
|
|
{
|
|
Id = memoryReferenceIdElement.GetString()!
|
|
};
|
|
variable.Name = variable.Id;
|
|
|
|
var output = Activator.CreateInstance(wrappedType, variable)!;
|
|
|
|
activity.SyntheticProperties[outputName] = output!;
|
|
}
|
|
}
|
|
|
|
private static bool GetBoolean(JsonElement element, string propertyName)
|
|
{
|
|
var propertyNames = new[] { propertyName.Camelize(), propertyName.Pascalize() };
|
|
|
|
foreach (var name in propertyNames)
|
|
{
|
|
if (element.TryGetProperty("customProperties", out var customPropertyElement))
|
|
{
|
|
if (customPropertyElement.TryGetProperty(name, out var canStartWorkflowElement))
|
|
return canStartWorkflowElement.GetBoolean();
|
|
}
|
|
|
|
if (element.TryGetProperty(propertyName.Camelize(), out var property) && property.GetBoolean())
|
|
return true;
|
|
}
|
|
|
|
return false;
|
|
}
|
|
}
|
|
|