using Serein.Library.Api;
using Serein.Library.Attributes;
using Serein.Library.Core.NodeFlow;
using Serein.Library.Entity;
using Serein.Library.Utils;
using System;
using System.Collections.Concurrent;
using System.ComponentModel;
using System.Reflection;
using System.Text.RegularExpressions;
namespace Serein.NodeFlow.Tool;
public static class NodeMethodDetailsHelper
{
///
/// 生成方法信息
///
///
///
///
//public static List GetList(Type type)
//{
// var methodDetailsDictionary = new List();
// var delegateDictionary = new List();
// var assemblyName = type.Assembly.GetName().Name;
// var methods = GetMethodsToProcess(type);
// foreach (var method in methods)
// {
// (var methodDetails,var methodDelegate) = CreateMethodDetails(type, method, assemblyName);
// methodDetailsDictionary.Add(methodDetails);
// delegateDictionary.Add(methodDelegate);
// }
// var mds = methodDetailsDictionary.OrderBy(it => it.MethodName).ToList();
// var dels = delegateDictionary;
// return mds;
//}
///
/// 获取处理方法
///
public static IEnumerable GetMethodsToProcess(Type type)
{
return type.GetMethods(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic)
.Where(m => m.GetCustomAttribute()?.Scan == true);
}
///
/// 创建方法信息
///
///
public static (MethodDetails?, DelegateDetails?) CreateMethodDetails(Type type, MethodInfo method, string assemblyName)
{
var attribute = method.GetCustomAttribute();
if(attribute is null || attribute.Scan == false)
{
return (null, null);
}
//var dllTypeName = $"{assemblyName}.{type.Name}";
var dllTypeMethodName = $"{assemblyName}.{type.Name}.{method.Name}";
var explicitDataOfParameters = GetExplicitDataOfParameters(method.GetParameters());
//// 通过表达式树生成委托
//var methodDelegate = GenerateMethodDelegate(type, // 方法所在的对象类型
// method, // 方法信息
// method.GetParameters(),// 方法参数
// method.ReturnType);// 返回值
//// 通过表达式树生成委托
var emitMethodType = EmitHelper.CreateDynamicMethod(method, out var methodDelegate);// 返回值
Type? returnType;
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]");
}
}
else if(isTask)
{
returnType = taskResult is null ? typeof(Task) : taskResult;
}
else
{
returnType = method.ReturnType;
}
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
{
ActingInstanceType = type,
// ActingInstance = instance,
MethodName = dllTypeMethodName,
MethodDynamicType = attribute.MethodDynamicType,
MethodLockName = attribute.LockName,
MethodTips = methodTips,
ExplicitDatas = explicitDataOfParameters,
ReturnType = returnType,
};
var dd = new DelegateDetails( emitMethodType, methodDelegate) ;
return (md, dd);
}
public static bool IsGenericTask(Type returnType, out Type? taskResult)
{
// 判断是否为 Task 类型或泛型 Task
if (returnType == typeof(Task))
{
taskResult = null;
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 ConvertorInstance =[];
///
/// 获取参数信息
///
///
///
private static ExplicitData[] GetExplicitDataOfParameters(ParameterInfo[] parameters)
{
return parameters.Select((it, index) =>
{
Type paremType;
if (it.GetCustomAttribute() is EnumTypeConvertorAttribute attribute1 && attribute1 is not null)
{
// 存在类型选择器
paremType = attribute1.EnumType;
return GetExplicitDataOfParameter(it, index, paremType, true);
}
else if (it.GetCustomAttribute() is BindConvertorAttribute attribute2 && attribute2 is not null)
{
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);
}
Func