using Serein.Library.Api; using Serein.Library.Attributes; using Serein.Library.Core.NodeFlow; using System.Collections.Concurrent; using System.Reflection; namespace Serein.NodeFlow.Tool; public static class DelegateCache { /// /// 委托缓存全局字典 /// public static ConcurrentDictionary GlobalDicDelegates { get; } = new ConcurrentDictionary(); } public static class DelegateGenerator { // 缓存的实例对象(键:类型名称) public static ConcurrentDictionary DynamicInstanceToType { get; } = new ConcurrentDictionary(); // 缓存的实例对象 (键:生成的方法名称) // public static ConcurrentDictionary DynamicInstance { get; } = new ConcurrentDictionary(); /// /// 生成方法信息 /// /// /// /// public static ConcurrentDictionary GenerateMethodDetails(ISereinIoc serviceContainer, Type type, bool isNetFramework) { var methodDetailsDictionary = new ConcurrentDictionary(); var assemblyName = type.Assembly.GetName().Name; var methods = GetMethodsToProcess(type, isNetFramework); foreach (var method in methods) { var methodDetails = CreateMethodDetails(serviceContainer, type, method, assemblyName, isNetFramework); methodDetailsDictionary.TryAdd(methodDetails.MethodName, methodDetails); } return methodDetailsDictionary; } /// /// 获取处理方法 /// private static IEnumerable GetMethodsToProcess(Type type, bool isNetFramework) { if (isNetFramework) { return type.GetMethods(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic) .Where(m => m.GetCustomAttribute()?.Scan == true); } else { return type.GetMethods(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic) .Where(m => m.GetCustomAttribute()?.Scan == true); } } /// /// 创建方法信息 /// /// private static MethodDetails CreateMethodDetails(ISereinIoc serviceContainer, Type type, MethodInfo method, string assemblyName, bool isNetFramework) { var methodName = method.Name; var attribute = method.GetCustomAttribute(); var explicitDataOfParameters = GetExplicitDataOfParameters(method.GetParameters()); // 生成委托 var methodDelegate = GenerateMethodDelegate(type, // 方法所在的对象类型 method, // 方法信息 method.GetParameters(),// 方法参数 method.ReturnType);// 返回值 var dllTypeName = $"{assemblyName}.{type.Name}"; serviceContainer.Register(type); object instance = serviceContainer.GetOrCreateServiceInstance(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, ReturnType = method.ReturnType, }; } private static ExplicitData[] GetExplicitDataOfParameters(ParameterInfo[] parameters) { return parameters.Select((it, index) => { //Console.WriteLine($"{it.Name}-{it.HasDefaultValue}-{it.DefaultValue}"); string explicitTypeName = GetExplicitTypeName(it.ParameterType); var items = GetExplicitItems(it.ParameterType, explicitTypeName); if ("Bool".Equals(explicitTypeName)) explicitTypeName = "Select"; // 布尔值 转为 可选类型 return new ExplicitData { IsExplicitData = it.HasDefaultValue, Index = index, ExplicitType = it.ParameterType, ExplicitTypeName = explicitTypeName, DataType = it.ParameterType, ParameterName = it.Name, DataValue = it.HasDefaultValue ? it.DefaultValue.ToString() : "", Items = items.ToArray(), }; }).ToArray(); } 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" }; } private static IEnumerable GetExplicitItems(Type type, string explicitTypeName) { return explicitTypeName switch { "Select" => Enum.GetNames(type), "Bool" => ["True", "False"], _ => [] }; } 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