Files
serein-flow/NodeFlow/Tool/MethodDetailsHelper.cs

219 lines
7.1 KiB
C#
Raw Normal View History

using Serein.Library.Api;
using Serein.Library.Attributes;
using Serein.Library.Core.NodeFlow;
using Serein.Library.Entity;
2024-09-27 10:30:19 +08:00
using System;
2024-08-06 16:09:46 +08:00
using System.Collections.Concurrent;
using System.Reflection;
namespace Serein.NodeFlow.Tool;
public static class MethodDetailsHelperTmp
2024-08-06 16:09:46 +08:00
{
/// <summary>
/// 生成方法信息
2024-08-06 16:09:46 +08:00
/// </summary>
/// <param name="serviceContainer"></param>
/// <param name="type"></param>
/// <returns></returns>
2024-09-25 22:20:23 +08:00
public static List<MethodDetails> GetList(Type type)
{
var methodDetailsDictionary = new List<MethodDetails>();
var assemblyName = type.Assembly.GetName().Name;
2024-09-25 22:20:23 +08:00
var methods = GetMethodsToProcess(type);
foreach (var method in methods)
{
2024-09-25 22:20:23 +08:00
var methodDetails = CreateMethodDetails(type, method, assemblyName);
methodDetailsDictionary.Add(methodDetails);
}
return methodDetailsDictionary.OrderBy(it => it.MethodName).ToList();
}
/// <summary>
/// 获取处理方法
/// </summary>
2024-09-25 22:20:23 +08:00
private static IEnumerable<MethodInfo> GetMethodsToProcess(Type type)
{
2024-09-25 22:20:23 +08:00
return type.GetMethods(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic)
.Where(m => m.GetCustomAttribute<NodeActionAttribute>()?.Scan == true);
}
/// <summary>
/// 创建方法信息
/// </summary>
/// <returns></returns>
2024-09-25 22:20:23 +08:00
private static MethodDetails CreateMethodDetails(Type type, MethodInfo method, string assemblyName)
{
var methodName = method.Name;
var attribute = method.GetCustomAttribute<NodeActionAttribute>();
2024-09-15 22:07:10 +08:00
if(attribute is null)
{
return null;
}
var explicitDataOfParameters = GetExplicitDataOfParameters(method.GetParameters());
// 生成委托
var methodDelegate = GenerateMethodDelegate(type, // 方法所在的对象类型
method, // 方法信息
method.GetParameters(),// 方法参数
method.ReturnType);// 返回值
2024-09-15 22:07:10 +08:00
Type returnType;
if (attribute?.MethodDynamicType == Library.Enums.NodeType.Flipflop)
{
// 触发器节点
returnType = attribute.ReturnType;
}
else
{
returnType = method.ReturnType;
}
var dllTypeName = $"{assemblyName}.{type.Name}";
// object instance = Activator.CreateInstance(type);
var dllTypeMethodName = $"{assemblyName}.{type.Name}.{method.Name}";
return new MethodDetails
{
ActingInstanceType = type,
// ActingInstance = instance,
MethodName = dllTypeMethodName,
MethodDelegate = methodDelegate,
MethodDynamicType = attribute.MethodDynamicType,
MethodLockName = attribute.LockName,
MethodTips = attribute.MethodTips,
ExplicitDatas = explicitDataOfParameters,
2024-09-15 22:07:10 +08:00
ReturnType = returnType,
};
}
2024-09-25 22:20:23 +08:00
/// <summary>
/// 获取参数信息
/// </summary>
/// <param name="parameters"></param>
/// <returns></returns>
private static ExplicitData[] GetExplicitDataOfParameters(ParameterInfo[] parameters)
{
return parameters.Select((it, index) =>
{
2024-09-25 22:20:23 +08:00
Type paremType;
2024-09-27 10:30:19 +08:00
var attribute = it.GetCustomAttribute<EnumTypeConvertorAttribute>();
if (attribute is not null)
{
// 存在选择器
paremType = attribute.EnumType;
}
else
{
paremType = it.ParameterType;
}
2024-09-25 22:20:23 +08:00
string explicitTypeName = GetExplicitTypeName(paremType);
var items = GetExplicitItems(paremType, explicitTypeName);
if ("Bool".Equals(explicitTypeName)) explicitTypeName = "Select"; // 布尔值 转为 可选类型
return new ExplicitData
{
2024-09-27 10:30:19 +08:00
IsExplicitData = attribute is null ? it.HasDefaultValue: true,
Index = index,
ExplicitTypeName = explicitTypeName,
2024-09-27 10:30:19 +08:00
ExplicitType = paremType,
DataType = it.ParameterType,
ParameterName = it.Name,
DataValue = it.HasDefaultValue ? it.DefaultValue.ToString() : "",
Items = items.ToArray(),
};
}).ToArray();
}
2024-09-25 22:20:23 +08:00
/// <summary>
/// 判断使用输入器还是选择器
/// </summary>
/// <param name="type"></param>
/// <returns></returns>
private static string GetExplicitTypeName(Type type)
{
return type switch
{
Type t when t.IsEnum => "Select",
Type t when t == typeof(bool) => "Bool",
Type t when t == typeof(string) => "Value",
Type t when t == typeof(int) => "Value",
Type t when t == typeof(double) => "Value",
_ => "Value"
};
}
2024-09-25 22:20:23 +08:00
/// <summary>
/// 获取参数列表选项
/// </summary>
/// <param name="type"></param>
/// <param name="explicitTypeName"></param>
/// <returns></returns>
private static IEnumerable<string> GetExplicitItems(Type type, string explicitTypeName)
{
2024-09-25 22:20:23 +08:00
IEnumerable<string> items = explicitTypeName switch
{
"Select" => Enum.GetNames(type),
"Bool" => ["True", "False"],
_ => []
};
2024-09-25 22:20:23 +08:00
return items;
}
private static Delegate GenerateMethodDelegate(Type type, MethodInfo methodInfo, ParameterInfo[] parameters, Type returnType)
{
var parameterTypes = parameters.Select(p => p.ParameterType).ToArray();
var parameterCount = parameters.Length;
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-08-06 16:09:46 +08:00
}