2024-09-12 20:32:54 +08:00
|
|
|
|
using Serein.Library.Api;
|
2024-10-10 10:45:53 +08:00
|
|
|
|
using Serein.Library.Utils;
|
2024-10-20 12:10:57 +08:00
|
|
|
|
using Serein.Library;
|
2024-08-06 16:09:46 +08:00
|
|
|
|
using System.Collections.Concurrent;
|
|
|
|
|
|
using System.Reflection;
|
2024-10-27 00:54:10 +08:00
|
|
|
|
using Serein.Library.FlowNode;
|
2024-11-02 22:11:38 +08:00
|
|
|
|
using System.Diagnostics;
|
2024-11-03 21:17:45 +08:00
|
|
|
|
using System.Diagnostics.CodeAnalysis;
|
2025-03-15 15:43:42 +08:00
|
|
|
|
using System.ComponentModel.DataAnnotations;
|
2025-03-15 16:03:58 +08:00
|
|
|
|
using System.ComponentModel;
|
2024-08-06 16:09:46 +08:00
|
|
|
|
|
|
|
|
|
|
namespace Serein.NodeFlow.Tool;
|
|
|
|
|
|
|
2024-10-10 20:52:19 +08:00
|
|
|
|
public static class NodeMethodDetailsHelper
|
2024-08-06 16:09:46 +08:00
|
|
|
|
{
|
2024-09-30 02:45:49 +08:00
|
|
|
|
|
2024-09-15 12:15:32 +08:00
|
|
|
|
/// <summary>
|
|
|
|
|
|
/// 获取处理方法
|
|
|
|
|
|
/// </summary>
|
2024-09-30 02:45:49 +08:00
|
|
|
|
public static IEnumerable<MethodInfo> GetMethodsToProcess(Type type)
|
2024-09-15 12:15:32 +08:00
|
|
|
|
{
|
2025-03-18 11:52:54 +08:00
|
|
|
|
return type.GetMethods(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Static)
|
2024-09-15 12:15:32 +08:00
|
|
|
|
.Where(m => m.GetCustomAttribute<NodeActionAttribute>()?.Scan == true);
|
|
|
|
|
|
}
|
2024-11-03 18:28:16 +08:00
|
|
|
|
|
2024-09-15 12:15:32 +08:00
|
|
|
|
/// <summary>
|
2024-11-03 21:17:45 +08:00
|
|
|
|
/// 创建方法信息/委托信息
|
2024-09-15 12:15:32 +08:00
|
|
|
|
/// </summary>
|
2024-11-03 21:17:45 +08:00
|
|
|
|
/// <param name="type">方法所属的类型</param>
|
|
|
|
|
|
/// <param name="methodInfo">方法信息</param>
|
|
|
|
|
|
/// <param name="assemblyName">方法所属的程序集名称</param>
|
|
|
|
|
|
/// <param name="methodDetails">创建的方法描述,用来生成节点信息</param>
|
|
|
|
|
|
/// <param name="delegateDetails">方法对应的Emit动态委托</param>
|
|
|
|
|
|
/// <returns>指示是否创建成功</returns>
|
|
|
|
|
|
public static bool TryCreateDetails(Type type,
|
|
|
|
|
|
MethodInfo methodInfo,
|
|
|
|
|
|
string assemblyName,
|
|
|
|
|
|
[MaybeNullWhen(false)] out MethodDetails methodDetails,
|
|
|
|
|
|
[MaybeNullWhen(false)] out DelegateDetails delegateDetails)
|
2024-09-15 12:15:32 +08:00
|
|
|
|
{
|
2024-11-03 21:17:45 +08:00
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
var attribute = methodInfo.GetCustomAttribute<NodeActionAttribute>();
|
2024-10-10 20:52:19 +08:00
|
|
|
|
if(attribute is null || attribute.Scan == false)
|
2024-09-15 22:07:10 +08:00
|
|
|
|
{
|
2024-11-03 21:17:45 +08:00
|
|
|
|
methodDetails = null;
|
|
|
|
|
|
delegateDetails = null;
|
|
|
|
|
|
return false;
|
2024-09-15 22:07:10 +08:00
|
|
|
|
}
|
2024-11-03 21:17:45 +08:00
|
|
|
|
|
2024-11-08 17:30:51 +08:00
|
|
|
|
var methodName = $"{assemblyName}.{type.Name}.{methodInfo.Name}";
|
2025-03-15 15:43:42 +08:00
|
|
|
|
|
2024-11-03 21:17:45 +08:00
|
|
|
|
// 创建参数信息
|
|
|
|
|
|
var explicitDataOfParameters = GetExplicitDataOfParameters(methodInfo.GetParameters());
|
2024-11-02 22:11:38 +08:00
|
|
|
|
|
2024-10-10 10:45:53 +08:00
|
|
|
|
//// 通过表达式树生成委托
|
|
|
|
|
|
//var methodDelegate = GenerateMethodDelegate(type, // 方法所在的对象类型
|
|
|
|
|
|
// method, // 方法信息
|
|
|
|
|
|
// method.GetParameters(),// 方法参数
|
|
|
|
|
|
// method.ReturnType);// 返回值
|
2024-09-15 12:15:32 +08:00
|
|
|
|
|
2024-11-04 23:30:52 +08:00
|
|
|
|
|
2024-10-07 15:15:18 +08:00
|
|
|
|
|
2024-10-07 22:52:10 +08:00
|
|
|
|
Type? returnType;
|
2024-11-03 21:17:45 +08:00
|
|
|
|
bool isTask = IsGenericTask(methodInfo.ReturnType, out var taskResult);
|
2024-10-07 15:15:18 +08:00
|
|
|
|
|
2025-03-15 15:43:42 +08:00
|
|
|
|
|
|
|
|
|
|
if (attribute.MethodDynamicType == Library.NodeType.UI)
|
|
|
|
|
|
{
|
|
|
|
|
|
if (isTask)
|
|
|
|
|
|
{
|
|
|
|
|
|
var innerType = methodInfo.ReturnType.GetGenericArguments()[0];
|
|
|
|
|
|
if (innerType.IsGenericType && innerType != typeof(IEmbeddedContent))
|
|
|
|
|
|
{
|
|
|
|
|
|
SereinEnv.WriteLine(InfoType.WARN, $"[{methodName}]跳过创建,因为UI方法的返回值并非IEmbeddedContent,流程工作台将无法正确显示自定义控件界面以及传递数据。");
|
|
|
|
|
|
methodDetails = null;
|
|
|
|
|
|
delegateDetails = null;
|
|
|
|
|
|
return false;
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
else
|
|
|
|
|
|
{
|
|
|
|
|
|
if (methodInfo.ReturnType != typeof(IEmbeddedContent))
|
|
|
|
|
|
{
|
|
|
|
|
|
SereinEnv.WriteLine(InfoType.WARN, $"[{methodName}]跳过创建,因为UI方法的返回值并非IEmbeddedContent,流程工作台将无法正确显示自定义控件界面以及传递数据。");
|
|
|
|
|
|
methodDetails = null;
|
|
|
|
|
|
delegateDetails = null;
|
|
|
|
|
|
return false;
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// 对于触发器
|
2024-10-20 12:10:57 +08:00
|
|
|
|
if (attribute.MethodDynamicType == Library.NodeType.Flipflop)
|
2024-09-15 22:07:10 +08:00
|
|
|
|
{
|
2024-11-03 21:17:45 +08:00
|
|
|
|
if (methodInfo.ReturnType.IsGenericType && methodInfo.ReturnType.GetGenericTypeDefinition() == typeof(Task<>))
|
2024-10-07 15:15:18 +08:00
|
|
|
|
{
|
2024-10-11 16:46:16 +08:00
|
|
|
|
// 获取 Task<> 的泛型参数类型
|
2024-11-03 21:17:45 +08:00
|
|
|
|
var innerType = methodInfo.ReturnType.GetGenericArguments()[0];
|
2024-10-11 16:46:16 +08:00
|
|
|
|
if (innerType.IsGenericType && innerType.GetGenericTypeDefinition() == typeof(IFlipflopContext<>))
|
|
|
|
|
|
{
|
|
|
|
|
|
var flipflopType = innerType.GetGenericArguments()[0];
|
|
|
|
|
|
returnType = flipflopType;
|
|
|
|
|
|
}
|
|
|
|
|
|
else
|
|
|
|
|
|
{
|
2024-11-08 17:30:51 +08:00
|
|
|
|
SereinEnv.WriteLine(InfoType.WARN, $"[{methodName}]跳过创建,返回类型非预期的Task<IFlipflopContext<TResult>>。");
|
2024-11-03 21:17:45 +08:00
|
|
|
|
methodDetails = null;
|
|
|
|
|
|
delegateDetails = null;
|
|
|
|
|
|
return false;
|
2024-10-11 16:46:16 +08:00
|
|
|
|
}
|
2024-10-07 15:15:18 +08:00
|
|
|
|
}
|
2024-10-11 16:46:16 +08:00
|
|
|
|
else
|
|
|
|
|
|
{
|
2024-11-08 17:30:51 +08:00
|
|
|
|
SereinEnv.WriteLine(InfoType.WARN, $"[{methodName}]跳过创建,因为触发器方法的返回值并非Task<>,将无法等待。");
|
2024-11-03 21:17:45 +08:00
|
|
|
|
methodDetails = null;
|
|
|
|
|
|
delegateDetails = null;
|
|
|
|
|
|
return false;
|
2024-10-11 16:46:16 +08:00
|
|
|
|
}
|
2024-10-07 15:15:18 +08:00
|
|
|
|
}
|
2025-03-15 15:43:42 +08:00
|
|
|
|
|
2024-10-07 15:15:18 +08:00
|
|
|
|
else if(isTask)
|
|
|
|
|
|
{
|
2024-10-07 22:52:10 +08:00
|
|
|
|
returnType = taskResult is null ? typeof(Task) : taskResult;
|
2024-09-15 22:07:10 +08:00
|
|
|
|
}
|
|
|
|
|
|
else
|
|
|
|
|
|
{
|
2024-11-03 21:17:45 +08:00
|
|
|
|
returnType = methodInfo.ReturnType;
|
2024-09-15 22:07:10 +08:00
|
|
|
|
}
|
2024-09-15 12:15:32 +08:00
|
|
|
|
|
2024-10-28 15:21:08 +08:00
|
|
|
|
if (string.IsNullOrEmpty(attribute.AnotherName)){
|
2024-11-03 21:17:45 +08:00
|
|
|
|
attribute.AnotherName = methodInfo.Name;
|
2024-10-07 15:15:18 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
var asyncPrefix = "[异步]"; // IsGenericTask(returnType) ? "[async]" : ;
|
2024-10-28 15:21:08 +08:00
|
|
|
|
var methodMethodAnotherName = isTask ? asyncPrefix + attribute.AnotherName : attribute.AnotherName;
|
2024-10-07 15:15:18 +08:00
|
|
|
|
|
2024-11-02 22:11:38 +08:00
|
|
|
|
bool hasParamsArg = false;
|
|
|
|
|
|
if (explicitDataOfParameters.Length > 0)
|
|
|
|
|
|
{
|
|
|
|
|
|
hasParamsArg = explicitDataOfParameters[^1].IsParams; // 取最后一个参数描述,判断是否为params 入参
|
|
|
|
|
|
}
|
2024-10-07 15:15:18 +08:00
|
|
|
|
|
2024-11-02 22:11:38 +08:00
|
|
|
|
var md = new MethodDetails() // 从DLL生成方法描述(元数据)
|
2024-09-15 12:15:32 +08:00
|
|
|
|
{
|
|
|
|
|
|
ActingInstanceType = type,
|
2024-11-03 21:17:45 +08:00
|
|
|
|
// ActingInstance = instance,
|
2025-03-15 15:43:42 +08:00
|
|
|
|
MethodName = NodeMethodDetailsHelper.GetMethodSignature(methodInfo),
|
2024-11-03 21:17:45 +08:00
|
|
|
|
AssemblyName = assemblyName,
|
2024-09-15 12:15:32 +08:00
|
|
|
|
MethodDynamicType = attribute.MethodDynamicType,
|
|
|
|
|
|
MethodLockName = attribute.LockName,
|
2024-10-28 15:21:08 +08:00
|
|
|
|
MethodAnotherName = methodMethodAnotherName,
|
2024-10-13 19:36:45 +08:00
|
|
|
|
ParameterDetailss = explicitDataOfParameters,
|
2024-09-15 22:07:10 +08:00
|
|
|
|
ReturnType = returnType,
|
2024-11-02 22:11:38 +08:00
|
|
|
|
// 如果存在可变参数,取最后一个元素的下标,否则为-1;
|
2024-11-03 21:17:45 +08:00
|
|
|
|
ParamsArgIndex = hasParamsArg ? explicitDataOfParameters.Length - 1 : -1,
|
2024-09-15 12:15:32 +08:00
|
|
|
|
};
|
2024-11-04 23:30:52 +08:00
|
|
|
|
|
|
|
|
|
|
//var emitMethodType = EmitHelper.CreateDynamicMethod(methodInfo, out var methodDelegate);// 返回值
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
var dd = new DelegateDetails(methodInfo) ; // 构造委托
|
2024-11-03 21:17:45 +08:00
|
|
|
|
|
|
|
|
|
|
methodDetails = md;
|
|
|
|
|
|
delegateDetails = dd;
|
|
|
|
|
|
return true;
|
2024-09-30 02:45:49 +08:00
|
|
|
|
|
2024-09-15 12:15:32 +08:00
|
|
|
|
}
|
2025-03-15 15:43:42 +08:00
|
|
|
|
public static string GetMethodSignature(MethodInfo method)
|
|
|
|
|
|
{
|
|
|
|
|
|
if (method == null) return string.Empty;
|
|
|
|
|
|
|
|
|
|
|
|
string methodName = method.Name;
|
2025-03-17 10:14:18 +08:00
|
|
|
|
//string returnType = method.ReturnType.Name;
|
2025-03-15 15:43:42 +08:00
|
|
|
|
string parameters = string.Join(", ", method.GetParameters()
|
|
|
|
|
|
.Select(p => $"{p.ParameterType.Name} {p.Name}"));
|
2024-09-15 12:15:32 +08:00
|
|
|
|
|
2025-03-17 10:14:18 +08:00
|
|
|
|
return $"{methodName}({parameters})";
|
|
|
|
|
|
//return $"{methodName}({parameters}) : {returnType}";
|
2025-03-15 15:43:42 +08:00
|
|
|
|
}
|
2024-10-07 22:52:10 +08:00
|
|
|
|
public static bool IsGenericTask(Type returnType, out Type? taskResult)
|
2024-10-07 15:15:18 +08:00
|
|
|
|
{
|
|
|
|
|
|
// 判断是否为 Task 类型或泛型 Task<T>
|
|
|
|
|
|
if (returnType == typeof(Task))
|
|
|
|
|
|
{
|
2024-10-07 22:52:10 +08:00
|
|
|
|
taskResult = null;
|
2024-10-07 15:15:18 +08:00
|
|
|
|
return true;
|
|
|
|
|
|
}
|
|
|
|
|
|
else if (returnType.IsGenericType && returnType.GetGenericTypeDefinition() == typeof(Task<>))
|
|
|
|
|
|
{
|
|
|
|
|
|
// 获取泛型参数类型
|
|
|
|
|
|
Type genericArgument = returnType.GetGenericArguments()[0];
|
|
|
|
|
|
taskResult = genericArgument;
|
|
|
|
|
|
return true;
|
|
|
|
|
|
}
|
|
|
|
|
|
else
|
|
|
|
|
|
{
|
|
|
|
|
|
taskResult = null;
|
|
|
|
|
|
return false;
|
|
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2024-09-28 23:55:19 +08:00
|
|
|
|
|
|
|
|
|
|
private static ConcurrentDictionary<string, (object, MethodInfo)> ConvertorInstance =[];
|
|
|
|
|
|
|
2024-09-25 22:20:23 +08:00
|
|
|
|
/// <summary>
|
|
|
|
|
|
/// 获取参数信息
|
|
|
|
|
|
/// </summary>
|
|
|
|
|
|
/// <param name="parameters"></param>
|
|
|
|
|
|
/// <returns></returns>
|
2024-10-13 19:36:45 +08:00
|
|
|
|
private static ParameterDetails[] GetExplicitDataOfParameters(ParameterInfo[] parameters)
|
2024-09-15 12:15:32 +08:00
|
|
|
|
{
|
|
|
|
|
|
|
2024-11-02 22:11:38 +08:00
|
|
|
|
var tempParams = parameters.Select((it, index) =>
|
2024-09-15 12:15:32 +08:00
|
|
|
|
{
|
2024-09-25 22:20:23 +08:00
|
|
|
|
Type paremType;
|
2024-11-02 22:11:38 +08:00
|
|
|
|
|
|
|
|
|
|
#region 存在“枚举=>类型”转换器
|
|
|
|
|
|
if (it.GetCustomAttribute<EnumTypeConvertorAttribute>() is EnumTypeConvertorAttribute attribute1 && attribute1 is not null)
|
2024-09-27 10:30:19 +08:00
|
|
|
|
{
|
2024-09-28 23:55:19 +08:00
|
|
|
|
// 存在类型选择器
|
|
|
|
|
|
paremType = attribute1.EnumType;
|
2024-11-02 22:11:38 +08:00
|
|
|
|
return GetExplicitDataOfParameter(it, index, paremType, true); // “枚举=>类型”转换器 获取参数
|
2024-09-27 10:30:19 +08:00
|
|
|
|
}
|
2024-11-02 22:11:38 +08:00
|
|
|
|
#endregion
|
|
|
|
|
|
#region 存在自定义的转换器
|
2024-09-28 23:55:19 +08:00
|
|
|
|
else if (it.GetCustomAttribute<BindConvertorAttribute>() is BindConvertorAttribute attribute2 && attribute2 is not null)
|
2024-09-27 10:30:19 +08:00
|
|
|
|
{
|
2024-09-28 23:55:19 +08:00
|
|
|
|
paremType = attribute2.EnumType;
|
|
|
|
|
|
|
|
|
|
|
|
string key = typeof(IEnumConvertor<,>).FullName + attribute2.EnumType.FullName + attribute2.ConvertorType.FullName;
|
|
|
|
|
|
|
|
|
|
|
|
if (!ConvertorInstance.ContainsKey(key))
|
|
|
|
|
|
{
|
|
|
|
|
|
Type enumConvertorType = typeof(IEnumConvertor<,>);
|
|
|
|
|
|
// 定义具体类型
|
|
|
|
|
|
Type specificType = enumConvertorType.MakeGenericType(attribute2.EnumType, it.ParameterType);
|
|
|
|
|
|
// 获取实现类的类型
|
|
|
|
|
|
Type implementorType = attribute2.ConvertorType;
|
|
|
|
|
|
// 创建实现类的实例
|
|
|
|
|
|
object instance = Activator.CreateInstance(implementorType);
|
|
|
|
|
|
// 调用 Convert 方法
|
|
|
|
|
|
MethodInfo convertMethod = implementorType.GetMethod("Convertor");
|
|
|
|
|
|
ConvertorInstance[key] = (instance, convertMethod);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2024-12-14 23:46:37 +08:00
|
|
|
|
//object func(object enumValue)
|
|
|
|
|
|
//{
|
|
|
|
|
|
// (var obj, var methodInfo) = ConvertorInstance[key];
|
|
|
|
|
|
// return methodInfo?.Invoke(obj, [enumValue]);
|
|
|
|
|
|
//}
|
|
|
|
|
|
|
2024-09-28 23:55:19 +08:00
|
|
|
|
// 确保实例实现了所需接口
|
2024-12-14 23:46:37 +08:00
|
|
|
|
ParameterDetails ed = GetExplicitDataOfParameter(it, index, paremType, true); // 自定义的转换器 获取参数
|
2024-09-28 23:55:19 +08:00
|
|
|
|
|
|
|
|
|
|
return ed;
|
2024-09-27 10:30:19 +08:00
|
|
|
|
}
|
2024-11-02 22:11:38 +08:00
|
|
|
|
#endregion
|
|
|
|
|
|
#region 常规方法的获取参数
|
2024-09-28 23:55:19 +08:00
|
|
|
|
else
|
2024-09-15 12:15:32 +08:00
|
|
|
|
{
|
2024-11-02 22:11:38 +08:00
|
|
|
|
var tmp = GetExplicitDataOfParameter(it, index, it.ParameterType, it.HasDefaultValue); // 常规方法的获取参数
|
|
|
|
|
|
return tmp;
|
|
|
|
|
|
}
|
|
|
|
|
|
#endregion
|
2024-09-28 23:55:19 +08:00
|
|
|
|
}).ToArray();
|
2024-11-02 22:11:38 +08:00
|
|
|
|
|
2025-05-30 11:53:33 +08:00
|
|
|
|
/* foreach(var pd in tempParams)
|
2025-03-15 15:43:42 +08:00
|
|
|
|
{
|
|
|
|
|
|
var argType = pd.DataType;
|
|
|
|
|
|
// 运行环境
|
|
|
|
|
|
if (typeof(IFlowEnvironment).IsAssignableFrom(argType))
|
|
|
|
|
|
{
|
|
|
|
|
|
continue;
|
|
|
|
|
|
}
|
|
|
|
|
|
// 流程上下文
|
|
|
|
|
|
if (typeof(IDynamicContext).IsAssignableFrom(argType))
|
|
|
|
|
|
{
|
|
|
|
|
|
continue;
|
|
|
|
|
|
}
|
|
|
|
|
|
// 节点模型
|
|
|
|
|
|
if (typeof(NodeModelBase).IsAssignableFrom(argType))
|
|
|
|
|
|
{
|
|
|
|
|
|
continue;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2025-05-30 11:53:33 +08:00
|
|
|
|
}*/
|
2024-11-02 22:11:38 +08:00
|
|
|
|
|
|
|
|
|
|
return tempParams;
|
2024-09-28 23:55:19 +08:00
|
|
|
|
}
|
2024-09-15 12:15:32 +08:00
|
|
|
|
|
2024-10-13 19:36:45 +08:00
|
|
|
|
private static ParameterDetails GetExplicitDataOfParameter(ParameterInfo parameterInfo,
|
2024-11-02 16:48:40 +08:00
|
|
|
|
int index,
|
2024-11-02 23:47:41 +08:00
|
|
|
|
Type explicitParemType,
|
2024-12-14 23:46:37 +08:00
|
|
|
|
bool isExplicitData)
|
2024-09-28 23:55:19 +08:00
|
|
|
|
{
|
2024-09-15 12:15:32 +08:00
|
|
|
|
|
2024-11-02 16:48:40 +08:00
|
|
|
|
bool hasParams = parameterInfo.IsDefined(typeof(ParamArrayAttribute)); // 判断是否为可变参数
|
2024-11-02 23:47:41 +08:00
|
|
|
|
Type dataType;
|
|
|
|
|
|
if (hasParams && parameterInfo.ParameterType.GetElementType() is Type paramsArgType) // 获取可变参数的子项类型
|
|
|
|
|
|
{
|
|
|
|
|
|
// 可选参数为 Array 类型,所以需要获取子项类型
|
|
|
|
|
|
// 如果 hasParams 为 true ,说明一定存在可选参数,所以 paramsArgType 一定不为 null
|
|
|
|
|
|
dataType = paramsArgType;
|
|
|
|
|
|
explicitParemType = paramsArgType;
|
|
|
|
|
|
}
|
|
|
|
|
|
else
|
|
|
|
|
|
{
|
|
|
|
|
|
dataType = parameterInfo.ParameterType;
|
|
|
|
|
|
}
|
2025-05-30 11:53:33 +08:00
|
|
|
|
isExplicitData = true;
|
|
|
|
|
|
string description = string.Empty; // 入参描述
|
|
|
|
|
|
var nodeParmsAttribute = parameterInfo.GetCustomAttribute<NodeParamAttribute>();
|
|
|
|
|
|
if(nodeParmsAttribute is not null)
|
|
|
|
|
|
{
|
|
|
|
|
|
if (!parameterInfo.HasDefaultValue)
|
|
|
|
|
|
{
|
|
|
|
|
|
isExplicitData = nodeParmsAttribute.IsExplicit; // 设置是否是显式参数
|
|
|
|
|
|
}
|
|
|
|
|
|
if (string.IsNullOrEmpty(nodeParmsAttribute.Name))
|
|
|
|
|
|
{
|
|
|
|
|
|
description = nodeParmsAttribute.Name; // 设置显示的名称
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
else
|
|
|
|
|
|
{
|
|
|
|
|
|
description = parameterInfo.GetCustomAttribute<DescriptionAttribute>()?.Description ?? string.Empty; // 判断是否存在注释特性
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2024-11-02 23:47:41 +08:00
|
|
|
|
|
2025-03-15 15:43:42 +08:00
|
|
|
|
var inputType = GetInputType(explicitParemType);
|
|
|
|
|
|
var items = GetExplicitItems(explicitParemType, inputType);
|
|
|
|
|
|
//if ("Bool".Equals(inputType)) inputType = "Select"; // 布尔值 转为 可选类型
|
2024-10-13 19:36:45 +08:00
|
|
|
|
return new ParameterDetails
|
2024-09-28 23:55:19 +08:00
|
|
|
|
{
|
|
|
|
|
|
IsExplicitData = isExplicitData, //attribute is null ? parameterInfo.HasDefaultValue : true,
|
2024-11-02 16:48:40 +08:00
|
|
|
|
Index = index, // 索引
|
2025-03-15 15:43:42 +08:00
|
|
|
|
InputType = inputType, // Select/Bool/Value
|
2024-11-02 23:47:41 +08:00
|
|
|
|
ExplicitType = explicitParemType,// 显示的入参类型
|
2024-12-14 23:46:37 +08:00
|
|
|
|
//Convertor = func, // 转换器
|
2024-11-02 23:47:41 +08:00
|
|
|
|
DataType = dataType, // 实际的入参类型
|
2024-10-13 19:36:45 +08:00
|
|
|
|
Name = parameterInfo.Name,
|
|
|
|
|
|
DataValue = parameterInfo.HasDefaultValue ? parameterInfo?.DefaultValue?.ToString() : "", // 如果存在默认值,则使用默认值
|
|
|
|
|
|
Items = items.ToArray(), // 如果是枚举值入参,则获取枚举类型的字面量
|
2024-11-02 16:48:40 +08:00
|
|
|
|
IsParams = hasParams, // 判断是否为可变参数
|
2025-03-15 16:03:58 +08:00
|
|
|
|
Description = description // 入参描述
|
|
|
|
|
|
|
2024-09-28 23:55:19 +08:00
|
|
|
|
};
|
2024-11-02 23:47:41 +08:00
|
|
|
|
|
2024-09-15 12:15:32 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
2024-09-28 23:55:19 +08:00
|
|
|
|
|
|
|
|
|
|
|
2024-09-25 22:20:23 +08:00
|
|
|
|
/// <summary>
|
|
|
|
|
|
/// 判断使用输入器还是选择器
|
|
|
|
|
|
/// </summary>
|
|
|
|
|
|
/// <param name="type"></param>
|
|
|
|
|
|
/// <returns></returns>
|
2025-03-15 15:43:42 +08:00
|
|
|
|
private static ParameterValueInputType GetInputType(Type type)
|
2024-09-15 12:15:32 +08:00
|
|
|
|
{
|
2024-10-20 12:10:57 +08:00
|
|
|
|
|
2024-09-15 12:15:32 +08:00
|
|
|
|
return type switch
|
|
|
|
|
|
{
|
2025-03-15 15:43:42 +08:00
|
|
|
|
Type t when t.IsEnum => ParameterValueInputType.Select,
|
|
|
|
|
|
Type t when t == typeof(bool) => ParameterValueInputType.Select,
|
|
|
|
|
|
Type t when t == typeof(string) => ParameterValueInputType.Input,
|
|
|
|
|
|
Type t when t == typeof(int) => ParameterValueInputType.Input,
|
|
|
|
|
|
Type t when t == typeof(double) => ParameterValueInputType.Input,
|
|
|
|
|
|
_ => ParameterValueInputType.Input
|
2024-09-15 12:15:32 +08:00
|
|
|
|
};
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2024-09-25 22:20:23 +08:00
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
|
/// 获取参数列表选项
|
|
|
|
|
|
/// </summary>
|
|
|
|
|
|
/// <param name="type"></param>
|
2025-03-15 15:43:42 +08:00
|
|
|
|
/// <param name="InputType"></param>
|
2024-09-25 22:20:23 +08:00
|
|
|
|
/// <returns></returns>
|
2025-03-15 15:43:42 +08:00
|
|
|
|
private static IEnumerable<string> GetExplicitItems(Type type, ParameterValueInputType InputType)
|
2024-09-15 12:15:32 +08:00
|
|
|
|
{
|
2025-03-15 15:43:42 +08:00
|
|
|
|
IEnumerable<string> items = InputType switch
|
2024-09-15 12:15:32 +08:00
|
|
|
|
{
|
2025-03-15 15:43:42 +08:00
|
|
|
|
ParameterValueInputType.Select when type == typeof(bool) => ["True", "False"],
|
|
|
|
|
|
ParameterValueInputType.Select => Enum.GetNames(type),
|
2024-09-15 12:15:32 +08:00
|
|
|
|
_ => []
|
|
|
|
|
|
};
|
2024-09-25 22:20:23 +08:00
|
|
|
|
return items;
|
2024-09-15 12:15:32 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
2024-10-10 10:45:53 +08:00
|
|
|
|
//private static Delegate GenerateMethodDelegate(Type type, MethodInfo methodInfo, ParameterInfo[] parameters, Type returnType)
|
|
|
|
|
|
//{
|
|
|
|
|
|
// var parameterTypes = parameters.Select(p => p.ParameterType).ToArray();
|
|
|
|
|
|
// var parameterCount = parameters.Length;
|
2024-09-15 12:15:32 +08:00
|
|
|
|
|
2024-10-10 10:45:53 +08:00
|
|
|
|
// if (returnType == typeof(void))
|
|
|
|
|
|
// {
|
|
|
|
|
|
// if (parameterCount == 0)
|
|
|
|
|
|
// {
|
|
|
|
|
|
// // 无返回值,无参数
|
|
|
|
|
|
// return ExpressionHelper.MethodCaller(type, methodInfo);
|
|
|
|
|
|
// }
|
|
|
|
|
|
// else
|
|
|
|
|
|
// {
|
|
|
|
|
|
// // 无返回值,有参数
|
|
|
|
|
|
// return ExpressionHelper.MethodCaller(type, methodInfo, parameterTypes);
|
|
|
|
|
|
// }
|
|
|
|
|
|
// }
|
|
|
|
|
|
// // else if (returnType == typeof(Task<FlipflopContext)) // 触发器
|
|
|
|
|
|
// else if (FlipflopFunc.IsTaskOfFlipflop(returnType)) // 触发器
|
|
|
|
|
|
// {
|
|
|
|
|
|
// if (parameterCount == 0)
|
|
|
|
|
|
// {
|
|
|
|
|
|
// // 有返回值,无参数
|
|
|
|
|
|
// return ExpressionHelper.MethodCallerAsync(type, methodInfo);
|
|
|
|
|
|
// }
|
|
|
|
|
|
// else
|
|
|
|
|
|
// {
|
|
|
|
|
|
// // 有返回值,有参数
|
|
|
|
|
|
// return ExpressionHelper.MethodCallerAsync(type, methodInfo, parameterTypes);
|
|
|
|
|
|
// }
|
|
|
|
|
|
// }
|
|
|
|
|
|
// else
|
|
|
|
|
|
// {
|
|
|
|
|
|
// if (parameterCount == 0)
|
|
|
|
|
|
// {
|
|
|
|
|
|
// // 有返回值,无参数
|
|
|
|
|
|
// return ExpressionHelper.MethodCallerHaveResult(type, methodInfo);
|
|
|
|
|
|
// }
|
|
|
|
|
|
// else
|
|
|
|
|
|
// {
|
|
|
|
|
|
// // 有返回值,有参数
|
|
|
|
|
|
// return ExpressionHelper.MethodCallerHaveResult(type, methodInfo, parameterTypes);
|
|
|
|
|
|
// }
|
|
|
|
|
|
// }
|
|
|
|
|
|
//}
|
2024-09-15 12:15:32 +08:00
|
|
|
|
|
2024-08-06 16:09:46 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
2024-09-15 12:15:32 +08:00
|
|
|
|
|