mirror of
https://gitee.com/langsisi_admin/serein-flow
synced 2026-03-20 00:06:45 +08:00
增强了实例工程的抽象逻辑
This commit is contained in:
@@ -231,7 +231,7 @@ namespace Serein.NodeFlow.Base
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
await Console.Out.WriteLineAsync(ex.ToString());
|
||||
await Console.Out.WriteLineAsync($"节点[{this.MethodDetails?.MethodName}]异常:" + ex.Message);
|
||||
NextOrientation = ConnectionType.IsError;
|
||||
RuningException = ex;
|
||||
return null;
|
||||
|
||||
@@ -956,7 +956,17 @@ namespace Serein.NodeFlow
|
||||
|
||||
List<Type> autoRegisterTypes = assembly.GetTypes().Where(t => t.GetCustomAttribute<AutoRegisterAttribute>() is not null).ToList();
|
||||
|
||||
List<Type> scanTypes = assembly.GetTypes().Where(t => t.GetCustomAttribute<DynamicFlowAttribute>()?.Scan == true).ToList();
|
||||
List<(Type, string)> scanTypes = assembly.GetTypes().Select(t => {
|
||||
if (t.GetCustomAttribute<DynamicFlowAttribute>() is DynamicFlowAttribute dynamicFlowAttribute
|
||||
&& dynamicFlowAttribute.Scan == true)
|
||||
{
|
||||
return (t, dynamicFlowAttribute.Name);
|
||||
}
|
||||
else
|
||||
{
|
||||
return (null, null);
|
||||
}
|
||||
}).Where(it => it.t is not null) .ToList();
|
||||
if (scanTypes.Count == 0)
|
||||
{
|
||||
return (null, [], []);
|
||||
@@ -964,7 +974,7 @@ namespace Serein.NodeFlow
|
||||
|
||||
List<MethodDetails> methodDetails = new List<MethodDetails>();
|
||||
// 遍历扫描的类型
|
||||
foreach (var type in scanTypes)
|
||||
foreach ((var type,var flowName ) in scanTypes)
|
||||
{
|
||||
// 加载DLL,创建 MethodDetails、实例作用对象、委托方法
|
||||
var assemblyName = type.Assembly.GetName().Name;
|
||||
@@ -981,6 +991,7 @@ namespace Serein.NodeFlow
|
||||
Console.WriteLine($"无法加载方法信息:{assemblyName}-{type}-{method}");
|
||||
continue;
|
||||
}
|
||||
md.MethodTips = flowName + md.MethodTips;
|
||||
if (MethodDelegates.TryAdd(md.MethodName, del))
|
||||
{
|
||||
methodDetails.Add(md);
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
using Serein.Library.Core.NodeFlow;
|
||||
using Serein.Library.Entity;
|
||||
using Serein.Library.Enums;
|
||||
using Serein.Library.Ex;
|
||||
using Serein.Library.Utils;
|
||||
using Serein.Library.Web;
|
||||
using Serein.NodeFlow.Base;
|
||||
@@ -385,9 +386,17 @@ namespace Serein.NodeFlow
|
||||
}
|
||||
}
|
||||
}
|
||||
catch(FlipflopException ex)
|
||||
{
|
||||
await Console.Out.WriteLineAsync($"触发器[{singleFlipFlopNode.MethodDetails.MethodName}]因非预期异常终止。"+ex.Message);
|
||||
if (ex.Clsss == FlipflopException.CancelClass.Flow)
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
await Console.Out.WriteLineAsync(ex.ToString());
|
||||
await Console.Out.WriteLineAsync(ex.Message);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -37,24 +37,31 @@ namespace Serein.NodeFlow.Model
|
||||
throw new Exception("不存在对应委托");
|
||||
}
|
||||
object instance = md.ActingInstance;
|
||||
// Task<IFlipflopContext>? flipflopTask = null;
|
||||
try
|
||||
{
|
||||
// 调用委托并获取结果
|
||||
//Task<IFlipflopContext> flipflopTask = md.ExplicitDatas.Length switch
|
||||
//{
|
||||
// 0 => ((Func<object, Task<IFlipflopContext>>)del).Invoke(md.ActingInstance),
|
||||
// _ => ((Func<object, object?[]?, Task<IFlipflopContext>>)del).Invoke(md.ActingInstance, GetParameters(context, this, md)), // 执行流程中的触发器方法时获取入参参数
|
||||
//};
|
||||
Task<IFlipflopContext> flipflopTask;
|
||||
if (md.ExplicitDatas.Length == 0)
|
||||
{
|
||||
flipflopTask = ((Func<object, Task<IFlipflopContext>>)del).Invoke(md.ActingInstance);
|
||||
if (del is Func<object, Task<IFlipflopContext>> function)
|
||||
{
|
||||
flipflopTask = function.Invoke(md.ActingInstance);
|
||||
}
|
||||
else
|
||||
{
|
||||
throw new FlipflopException("触发节点非预期的返回类型", true, FlipflopException.CancelClass.Flow);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
var parameters = GetParameters(context, this, md);
|
||||
flipflopTask = ((Func<object, object?[]?, Task<IFlipflopContext>>)del).Invoke(md.ActingInstance, parameters);
|
||||
if(del is Func<object, object?[]?, Task<IFlipflopContext>> function)
|
||||
{
|
||||
flipflopTask = function.Invoke(md.ActingInstance, parameters);
|
||||
}
|
||||
else
|
||||
{
|
||||
throw new FlipflopException("触发节点非预期的返回类型", true,FlipflopException.CancelClass.Flow);
|
||||
}
|
||||
}
|
||||
|
||||
IFlipflopContext flipflopContext = (await flipflopTask) ?? throw new FlipflopException("没有返回上下文");
|
||||
@@ -67,14 +74,18 @@ namespace Serein.NodeFlow.Model
|
||||
}
|
||||
catch (FlipflopException ex)
|
||||
{
|
||||
await Console.Out.WriteLineAsync(ex.ToString());
|
||||
if(ex.Clsss == FlipflopException.CancelClass.Flow)
|
||||
{
|
||||
throw;
|
||||
}
|
||||
await Console.Out.WriteLineAsync($"触发器[{this.MethodDetails.MethodName}]异常:" + ex.Message);
|
||||
NextOrientation = ConnectionType.None;
|
||||
RuningException = ex;
|
||||
return null;
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
await Console.Out.WriteLineAsync(ex.ToString());
|
||||
await Console.Out.WriteLineAsync($"触发器[{this.MethodDetails.MethodName}]异常:" + ex.Message);
|
||||
NextOrientation = ConnectionType.IsError;
|
||||
RuningException = ex;
|
||||
return null;
|
||||
|
||||
@@ -6,6 +6,7 @@ using System;
|
||||
using System.Collections.Concurrent;
|
||||
using System.ComponentModel;
|
||||
using System.Reflection;
|
||||
using System.Text.RegularExpressions;
|
||||
|
||||
namespace Serein.NodeFlow.Tool;
|
||||
|
||||
@@ -54,13 +55,14 @@ public static class MethodDetailsHelperTmp
|
||||
/// <returns></returns>
|
||||
public static (MethodDetails?,Delegate?) CreateMethodDetails(Type type, MethodInfo method, string assemblyName)
|
||||
{
|
||||
|
||||
var methodName = method.Name;
|
||||
var attribute = method.GetCustomAttribute<NodeActionAttribute>();
|
||||
if(attribute is null)
|
||||
{
|
||||
return (null, null);
|
||||
}
|
||||
//var dllTypeName = $"{assemblyName}.{type.Name}";
|
||||
var dllTypeMethodName = $"{assemblyName}.{type.Name}.{method.Name}";
|
||||
|
||||
var explicitDataOfParameters = GetExplicitDataOfParameters(method.GetParameters());
|
||||
//// 生成委托
|
||||
var methodDelegate = GenerateMethodDelegate(type, // 方法所在的对象类型
|
||||
@@ -68,20 +70,38 @@ public static class MethodDetailsHelperTmp
|
||||
method.GetParameters(),// 方法参数
|
||||
method.ReturnType);// 返回值
|
||||
|
||||
|
||||
Type returnType;
|
||||
if (attribute?.MethodDynamicType == Library.Enums.NodeType.Flipflop)
|
||||
bool isTask = IsGenericTask(method.ReturnType, out var taskResult);
|
||||
|
||||
if (attribute.MethodDynamicType == Library.Enums.NodeType.Flipflop)
|
||||
{
|
||||
// 触发器节点
|
||||
returnType = attribute.ReturnType;
|
||||
if (!isTask || taskResult != typeof(IFlipflopContext))
|
||||
{
|
||||
Console.WriteLine($"触发器节点的返回类型非预期类型,可能会导致流程异常。[{dllTypeMethodName}]当前返回类型为[{method.ReturnType}],而预期的返回类型应为[Task<IFlipflopContext>]");
|
||||
}
|
||||
|
||||
}
|
||||
else if(isTask)
|
||||
{
|
||||
returnType = taskResult;
|
||||
}
|
||||
else
|
||||
{
|
||||
returnType = method.ReturnType;
|
||||
}
|
||||
|
||||
var dllTypeName = $"{assemblyName}.{type.Name}";
|
||||
// object instance = Activator.CreateInstance(type);
|
||||
var dllTypeMethodName = $"{assemblyName}.{type.Name}.{method.Name}";
|
||||
if (string.IsNullOrEmpty(attribute.MethodTips)){
|
||||
attribute.MethodTips = method.Name;
|
||||
}
|
||||
|
||||
|
||||
|
||||
var asyncPrefix = "[异步]"; // IsGenericTask(returnType) ? "[async]" : ;
|
||||
var methodTips = isTask ? asyncPrefix + attribute.MethodTips : attribute.MethodTips;
|
||||
|
||||
|
||||
|
||||
var md = new MethodDetails
|
||||
{
|
||||
@@ -90,7 +110,7 @@ public static class MethodDetailsHelperTmp
|
||||
MethodName = dllTypeMethodName,
|
||||
MethodDynamicType = attribute.MethodDynamicType,
|
||||
MethodLockName = attribute.LockName,
|
||||
MethodTips = attribute.MethodTips,
|
||||
MethodTips = methodTips,
|
||||
ExplicitDatas = explicitDataOfParameters,
|
||||
ReturnType = returnType,
|
||||
};
|
||||
@@ -99,6 +119,29 @@ public static class MethodDetailsHelperTmp
|
||||
|
||||
}
|
||||
|
||||
public static bool IsGenericTask(Type returnType, out Type taskResult)
|
||||
{
|
||||
// 判断是否为 Task 类型或泛型 Task<T>
|
||||
if (returnType == typeof(Task))
|
||||
{
|
||||
taskResult = returnType;
|
||||
return true;
|
||||
}
|
||||
else if (returnType.IsGenericType && returnType.GetGenericTypeDefinition() == typeof(Task<>))
|
||||
{
|
||||
// 获取泛型参数类型
|
||||
Type genericArgument = returnType.GetGenericArguments()[0];
|
||||
taskResult = genericArgument;
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
taskResult = null;
|
||||
return false;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private static ConcurrentDictionary<string, (object, MethodInfo)> ConvertorInstance =[];
|
||||
|
||||
|
||||
Reference in New Issue
Block a user