mirror of
https://gitee.com/langsisi_admin/serein-flow
synced 2026-03-17 23:16:39 +08:00
重写了节点的view、viewmodel关系,实现了对画布元素的选取功能,重构了底层依赖,添加了对net .Framework4.6.1以上的Framework类库支持
This commit is contained in:
192
Library.Core/Flow/Tool/DelegateGenerator.cs
Normal file
192
Library.Core/Flow/Tool/DelegateGenerator.cs
Normal file
@@ -0,0 +1,192 @@
|
||||
using Serein.Library.IOC;
|
||||
using System.Collections.Concurrent;
|
||||
using System.Reflection;
|
||||
|
||||
namespace Serein.Flow.Tool;
|
||||
|
||||
|
||||
public static class DelegateCache
|
||||
{
|
||||
/// <summary>
|
||||
/// 委托缓存全局字典
|
||||
/// </summary>
|
||||
public static ConcurrentDictionary<string, Delegate> GlobalDicDelegates { get; } = new ConcurrentDictionary<string, Delegate>();
|
||||
}
|
||||
|
||||
public static class DelegateGenerator
|
||||
{
|
||||
// 缓存的实例对象(键:类型名称)
|
||||
public static ConcurrentDictionary<string, object> DynamicInstanceToType { get; } = new ConcurrentDictionary<string, object>();
|
||||
// 缓存的实例对象 (键:生成的方法名称)
|
||||
// public static ConcurrentDictionary<string, object> DynamicInstance { get; } = new ConcurrentDictionary<string, object>();
|
||||
|
||||
/// <summary>
|
||||
/// 生成方法信息
|
||||
/// </summary>
|
||||
/// <param name="serviceContainer"></param>
|
||||
/// <param name="type"></param>
|
||||
/// <returns></returns>
|
||||
public static ConcurrentDictionary<string, MethodDetails> GenerateMethodDetails(IServiceContainer serviceContainer, Type type)
|
||||
{
|
||||
var methodDetailsDictionary = new ConcurrentDictionary<string, MethodDetails>();
|
||||
var assemblyName = type.Assembly.GetName().Name;
|
||||
var methods = GetMethodsToProcess(type);
|
||||
|
||||
foreach (var method in methods)
|
||||
{
|
||||
|
||||
var methodDetails = CreateMethodDetails(serviceContainer, type, method, assemblyName);
|
||||
|
||||
methodDetailsDictionary.TryAdd(methodDetails.MethodName, methodDetails);
|
||||
}
|
||||
|
||||
return methodDetailsDictionary;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 获取处理方法
|
||||
/// </summary>
|
||||
private static IEnumerable<MethodInfo> GetMethodsToProcess(Type type)
|
||||
{
|
||||
return type.GetMethods(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic)
|
||||
.Where(m => m.GetCustomAttribute<MethodDetailAttribute>()?.Scan == true);
|
||||
}
|
||||
/// <summary>
|
||||
/// 创建方法信息
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
private static MethodDetails CreateMethodDetails(IServiceContainer serviceContainer, Type type, MethodInfo method, string assemblyName)
|
||||
{
|
||||
var methodName = method.Name;
|
||||
var attribute = method.GetCustomAttribute<MethodDetailAttribute>();
|
||||
|
||||
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.GetCustomAttribute(typeof(ExplicitAttribute)) is ExplicitAttribute,
|
||||
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<string> 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<FlipflopContext>)) // 触发器
|
||||
{
|
||||
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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
194
Library.Core/Flow/Tool/DynamicTool.cs
Normal file
194
Library.Core/Flow/Tool/DynamicTool.cs
Normal file
@@ -0,0 +1,194 @@
|
||||
namespace Serein.Flow.Tool
|
||||
{
|
||||
|
||||
#region 锁、tsk工具 (已注释)
|
||||
/*public class LockManager
|
||||
{
|
||||
private readonly ConcurrentDictionary<string, LockQueue> _locks = new ConcurrentDictionary<string, LockQueue>();
|
||||
|
||||
public void CreateLock(string name)
|
||||
{
|
||||
_locks.TryAdd(name, new LockQueue());
|
||||
}
|
||||
|
||||
public async Task AcquireLockAsync(string name, CancellationToken cancellationToken = default)
|
||||
{
|
||||
if (!_locks.ContainsKey(name))
|
||||
{
|
||||
throw new ArgumentException($"Lock with name '{name}' does not exist.");
|
||||
}
|
||||
|
||||
var lockQueue = _locks[name];
|
||||
var tcs = new TaskCompletionSource<bool>(TaskCreationOptions.RunContinuationsAsynchronously);
|
||||
|
||||
lock (lockQueue.Queue)
|
||||
{
|
||||
lockQueue.Queue.Enqueue(tcs);
|
||||
if (lockQueue.Queue.Count == 1)
|
||||
{
|
||||
tcs.SetResult(true);
|
||||
}
|
||||
}
|
||||
|
||||
await tcs.Task.ConfigureAwait(false);
|
||||
|
||||
// 处理取消操作
|
||||
if (cancellationToken.CanBeCanceled)
|
||||
{
|
||||
cancellationToken.Register(() =>
|
||||
{
|
||||
lock (lockQueue.Queue)
|
||||
{
|
||||
if (lockQueue.Queue.Contains(tcs))
|
||||
{
|
||||
tcs.TrySetCanceled();
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
public void ReleaseLock(string name)
|
||||
{
|
||||
if (!_locks.ContainsKey(name))
|
||||
{
|
||||
throw new ArgumentException($"Lock with name '{name}' does not exist.");
|
||||
}
|
||||
|
||||
var lockQueue = _locks[name];
|
||||
|
||||
lock (lockQueue.Queue)
|
||||
{
|
||||
if (lockQueue.Queue.Count > 0)
|
||||
{
|
||||
lockQueue.Queue.Dequeue();
|
||||
|
||||
if (lockQueue.Queue.Count > 0)
|
||||
{
|
||||
var next = lockQueue.Queue.Peek();
|
||||
next.SetResult(true);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private class LockQueue
|
||||
{
|
||||
public Queue<TaskCompletionSource<bool>> Queue { get; } = new Queue<TaskCompletionSource<bool>>();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public interface ITaskResult
|
||||
{
|
||||
object Result { get; }
|
||||
}
|
||||
|
||||
public class TaskResult<T> : ITaskResult
|
||||
{
|
||||
public TaskResult(T result)
|
||||
{
|
||||
Result = result;
|
||||
}
|
||||
|
||||
public T Result { get; }
|
||||
|
||||
object ITaskResult.Result => Result;
|
||||
}
|
||||
|
||||
public class DynamicTasks
|
||||
{
|
||||
private static readonly ConcurrentDictionary<string, Task<ITaskResult>> TaskGuidPairs = new();
|
||||
public static Task<ITaskResult> GetTask(string Guid)
|
||||
{
|
||||
TaskGuidPairs.TryGetValue(Guid, out Task<ITaskResult> task);
|
||||
return task;
|
||||
}
|
||||
|
||||
public static bool AddTask<T>(string Guid, T result)
|
||||
{
|
||||
var task = Task.FromResult<ITaskResult>(new TaskResult<T>(result));
|
||||
|
||||
return TaskGuidPairs.TryAdd(Guid, task);
|
||||
}
|
||||
}
|
||||
public class TaskNodeManager
|
||||
{
|
||||
private readonly ConcurrentDictionary<string, TaskQueue> _taskQueues = new ConcurrentDictionary<string, TaskQueue>();
|
||||
|
||||
public void CreateTaskNode(string name)
|
||||
{
|
||||
_taskQueues.TryAdd(name, new TaskQueue());
|
||||
}
|
||||
|
||||
public async Task WaitForTaskNodeAsync(string name, CancellationToken cancellationToken = default)
|
||||
{
|
||||
if (!_taskQueues.ContainsKey(name))
|
||||
{
|
||||
throw new ArgumentException($"Task node with name '{name}' does not exist.");
|
||||
}
|
||||
|
||||
var taskQueue = _taskQueues[name];
|
||||
var tcs = new TaskCompletionSource<bool>(TaskCreationOptions.RunContinuationsAsynchronously);
|
||||
|
||||
lock (taskQueue.Queue)
|
||||
{
|
||||
taskQueue.Queue.Enqueue(tcs);
|
||||
if (taskQueue.Queue.Count == 1)
|
||||
{
|
||||
tcs.SetResult(true);
|
||||
}
|
||||
}
|
||||
|
||||
await tcs.Task.ConfigureAwait(false);
|
||||
|
||||
// 处理取消操作
|
||||
if (cancellationToken.CanBeCanceled)
|
||||
{
|
||||
cancellationToken.Register(() =>
|
||||
{
|
||||
lock (taskQueue.Queue)
|
||||
{
|
||||
if (taskQueue.Queue.Contains(tcs))
|
||||
{
|
||||
tcs.TrySetCanceled();
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
public void CompleteTaskNode(string name)
|
||||
{
|
||||
if (!_taskQueues.ContainsKey(name))
|
||||
{
|
||||
throw new ArgumentException($"Task node with name '{name}' does not exist.");
|
||||
}
|
||||
|
||||
var taskQueue = _taskQueues[name];
|
||||
|
||||
lock (taskQueue.Queue)
|
||||
{
|
||||
if (taskQueue.Queue.Count > 0)
|
||||
{
|
||||
taskQueue.Queue.Dequeue();
|
||||
|
||||
if (taskQueue.Queue.Count > 0)
|
||||
{
|
||||
var next = taskQueue.Queue.Peek();
|
||||
next.SetResult(true);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private class TaskQueue
|
||||
{
|
||||
public Queue<TaskCompletionSource<bool>> Queue { get; } = new Queue<TaskCompletionSource<bool>>();
|
||||
}
|
||||
}*/
|
||||
#endregion
|
||||
|
||||
|
||||
|
||||
}
|
||||
740
Library.Core/Flow/Tool/ExpressionHelper.cs
Normal file
740
Library.Core/Flow/Tool/ExpressionHelper.cs
Normal file
@@ -0,0 +1,740 @@
|
||||
using System.Collections.Concurrent;
|
||||
using System.Linq.Expressions;
|
||||
using System.Reflection;
|
||||
|
||||
namespace Serein.Flow.Tool
|
||||
{
|
||||
/// <summary>
|
||||
/// 对于实例创建的表达式树反射
|
||||
/// </summary>
|
||||
public static class ExpressionHelper
|
||||
{
|
||||
/// <summary>
|
||||
/// 缓存表达式树反射方法
|
||||
/// </summary>
|
||||
private static ConcurrentDictionary<string, Delegate> Cache { get; } = new ConcurrentDictionary<string, Delegate>();
|
||||
|
||||
public static List<string> GetCacheKey()
|
||||
{
|
||||
return [.. Cache.Keys];
|
||||
}
|
||||
|
||||
#region 基于类型的表达式反射构建委托
|
||||
|
||||
#region 属性、字段的委托创建(表达式反射)
|
||||
|
||||
/// <summary>
|
||||
/// 动态获取属性值
|
||||
/// </summary>
|
||||
public static Delegate PropertyGetter(Type type, string propertyName)
|
||||
{
|
||||
string cacheKey = $"{type.FullName}.{propertyName}.Getter";
|
||||
return Cache.GetOrAdd(cacheKey, _ => CreateGetterDelegate(type, propertyName));
|
||||
}
|
||||
/// <summary>
|
||||
/// 动态获取属性值
|
||||
/// </summary>
|
||||
private static Delegate CreateGetterDelegate(Type type, string propertyName)
|
||||
{
|
||||
var parameter = Expression.Parameter(typeof(object), "instance");
|
||||
var property = Expression.Property(Expression.Convert(parameter, type), propertyName);
|
||||
var lambda = Expression.Lambda(Expression.Convert(property, typeof(object)), parameter);
|
||||
return lambda.Compile();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 动态设置属性值
|
||||
/// </summary>
|
||||
public static Delegate PropertySetter(Type type, string propertyName)
|
||||
{
|
||||
string cacheKey = $"{type.FullName}.{propertyName}.Setter";
|
||||
return Cache.GetOrAdd(cacheKey, _ => CreateSetterDelegate(type, propertyName));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 动态设置属性值
|
||||
/// </summary>
|
||||
private static Delegate CreateSetterDelegate(Type type, string propertyName)
|
||||
{
|
||||
var parameter = Expression.Parameter(typeof(object), "instance");
|
||||
var value = Expression.Parameter(typeof(object), "value");
|
||||
var property = Expression.Property(Expression.Convert(parameter, type), propertyName);
|
||||
var assign = Expression.Assign(property, Expression.Convert(value, property.Type));
|
||||
var lambda = Expression.Lambda(assign, parameter, value);
|
||||
return lambda.Compile();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 动态获取字段值
|
||||
/// </summary>
|
||||
public static Delegate FieldGetter(Type type, string fieldName)
|
||||
{
|
||||
string cacheKey = $"{type.FullName}.{fieldName}.FieldGetter";
|
||||
return Cache.GetOrAdd(cacheKey, _ => CreateFieldGetterDelegate(type, fieldName));
|
||||
}
|
||||
/// <summary>
|
||||
/// 动态获取字段值
|
||||
/// </summary>
|
||||
private static Delegate CreateFieldGetterDelegate(Type type, string fieldName)
|
||||
{
|
||||
var parameter = Expression.Parameter(typeof(object), "instance");
|
||||
var field = Expression.Field(Expression.Convert(parameter, type), fieldName);
|
||||
var lambda = Expression.Lambda(Expression.Convert(field, typeof(object)), parameter);
|
||||
return lambda.Compile();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 动态设置字段值
|
||||
/// </summary>
|
||||
public static Delegate FieldSetter(Type type, string fieldName)
|
||||
{
|
||||
string cacheKey = $"{type.FullName}.{fieldName}.FieldSetter";
|
||||
return Cache.GetOrAdd(cacheKey, _ => CreateFieldSetterDelegate(type, fieldName));
|
||||
}
|
||||
/// <summary>
|
||||
/// 动态设置字段值
|
||||
/// </summary>
|
||||
private static Delegate CreateFieldSetterDelegate(Type type, string fieldName)
|
||||
{
|
||||
var parameter = Expression.Parameter(typeof(object), "instance");
|
||||
var value = Expression.Parameter(typeof(object), "value");
|
||||
var field = Expression.Field(Expression.Convert(parameter, type), fieldName);
|
||||
var assign = Expression.Assign(field, Expression.Convert(value, field.Type));
|
||||
var lambda = Expression.Lambda(assign, parameter, value);
|
||||
return lambda.Compile();
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// 表达式树构建无参数,无返回值方法
|
||||
/// </summary>
|
||||
public static Delegate MethodCaller(Type type, MethodInfo methodInfo)
|
||||
{
|
||||
string cacheKey = $"{type.FullName}.{methodInfo.Name}.MethodCaller";
|
||||
return Cache.GetOrAdd(cacheKey, _ => CreateMethodCallerDelegate(type, methodInfo));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 表达式树构建无参数,无返回值方法
|
||||
/// </summary>
|
||||
private static Delegate CreateMethodCallerDelegate(Type type, MethodInfo methodInfo)
|
||||
{
|
||||
var parameter = Expression.Parameter(typeof(object), "instance");
|
||||
var methodCall = Expression.Call(Expression.Convert(parameter, type), methodInfo);
|
||||
var lambda = Expression.Lambda(methodCall, parameter);
|
||||
// Action<object>
|
||||
return lambda.Compile();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 表达式树构建无参数,有返回值方法
|
||||
/// </summary>
|
||||
public static Delegate MethodCallerHaveResult(Type type, MethodInfo methodInfo)
|
||||
{
|
||||
string cacheKey = $"{type.FullName}.{methodInfo.Name}.MethodCallerHaveResult";
|
||||
return Cache.GetOrAdd(cacheKey, _ => CreateMethodCallerDelegateHaveResult(type, methodInfo));
|
||||
}
|
||||
/// <summary>
|
||||
/// 表达式树构建无参数,有返回值方法
|
||||
/// </summary>
|
||||
private static Delegate CreateMethodCallerDelegateHaveResult(Type type, MethodInfo methodInfo)
|
||||
{
|
||||
var parameter = Expression.Parameter(typeof(object), "instance");
|
||||
var methodCall = Expression.Call(Expression.Convert(parameter, type), methodInfo);
|
||||
var lambda = Expression.Lambda(Expression.Convert(methodCall, typeof(object)), parameter);
|
||||
// Func<object, object>
|
||||
return lambda.Compile();
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// 表达式树构建多个参数,无返回值的方法
|
||||
/// </summary>
|
||||
public static Delegate MethodCaller(Type type, MethodInfo methodInfo, params Type[] parameterTypes)
|
||||
{
|
||||
string cacheKey = $"{type.FullName}.{methodInfo.Name}.MethodCaller";
|
||||
return Cache.GetOrAdd(cacheKey, _ => CreateMethodCallerDelegate(type, methodInfo, parameterTypes));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 表达式树构建多个参数,无返回值的方法
|
||||
/// </summary>
|
||||
private static Delegate CreateMethodCallerDelegate(Type type, MethodInfo methodInfo, Type[] parameterTypes)
|
||||
{
|
||||
/* var parameter = Expression.Parameter(typeof(object), "instance");
|
||||
|
||||
var arguments = parameterTypes.Select((t, i) => Expression.Parameter(typeof(object), $"arg{i}")).ToArray();
|
||||
|
||||
var convertedArguments = arguments.Select((arg, i) => Expression.Convert(arg, parameterTypes[i])).ToArray();
|
||||
var methodCall = Expression.Call(Expression.Convert(parameter, type),
|
||||
methodInfo,
|
||||
convertedArguments);
|
||||
var lambda = Expression.Lambda(methodCall, new[] { parameter }.Concat(arguments));
|
||||
var tmpAction = lambda.Compile();
|
||||
|
||||
// Action<object, object[]>
|
||||
return lambda.Compile();*/
|
||||
|
||||
var instanceParam = Expression.Parameter(typeof(object), "instance");
|
||||
var argsParam = Expression.Parameter(typeof(object[]), "args");
|
||||
|
||||
// 创建参数表达式
|
||||
var convertedArgs = parameterTypes.Select((paramType, index) =>
|
||||
Expression.Convert(Expression.ArrayIndex(argsParam, Expression.Constant(index)), paramType)
|
||||
).ToArray();
|
||||
|
||||
|
||||
// 创建方法调用表达式
|
||||
var methodCall = Expression.Call(
|
||||
Expression.Convert(instanceParam, type),
|
||||
methodInfo,
|
||||
(Expression[])convertedArgs
|
||||
);
|
||||
|
||||
// 创建 lambda 表达式
|
||||
var lambda = Expression.Lambda(
|
||||
methodCall,
|
||||
instanceParam,
|
||||
argsParam
|
||||
);
|
||||
|
||||
// Func<object, object[], object>
|
||||
return lambda.Compile();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 表达式树构建多个参数,有返回值的方法
|
||||
/// </summary>
|
||||
public static Delegate MethodCallerHaveResult(Type type, MethodInfo methodInfo, Type[] parameterTypes)
|
||||
{
|
||||
string cacheKey = $"{type.FullName}.{methodInfo.Name}.MethodCallerHaveResult";
|
||||
return Cache.GetOrAdd(cacheKey, _ => CreateMethodCallerDelegateHaveResult(type, methodInfo, parameterTypes));
|
||||
}
|
||||
/// <summary>
|
||||
/// 表达式树构建多个参数,有返回值的方法
|
||||
/// </summary>
|
||||
private static Delegate CreateMethodCallerDelegateHaveResult(Type type, MethodInfo methodInfo, Type[] parameterTypes)
|
||||
{
|
||||
/*var instanceParam = Expression.Parameter(typeof(object), "instance");
|
||||
var argsParam = Expression.Parameter(typeof(object[]), "args");
|
||||
|
||||
// 创建参数表达式
|
||||
var convertedArgs = parameterTypes.Select((paramType, index) =>
|
||||
Expression.Convert(Expression.ArrayIndex(argsParam, Expression.Constant(index)), paramType)
|
||||
).ToArray();
|
||||
|
||||
|
||||
// 创建方法调用表达式
|
||||
var methodCall = Expression.Call(
|
||||
Expression.Convert(instanceParam, type),
|
||||
methodInfo,
|
||||
convertedArgs
|
||||
);
|
||||
|
||||
// 创建 lambda 表达式
|
||||
var lambda = Expression.Lambda(
|
||||
Expression.Convert(methodCall, typeof(object)),
|
||||
instanceParam,
|
||||
argsParam
|
||||
);
|
||||
|
||||
// Func<object, object[], object>
|
||||
return lambda.Compile();*/
|
||||
|
||||
var instanceParam = Expression.Parameter(typeof(object), "instance");
|
||||
var argsParam = Expression.Parameter(typeof(object[]), "args");
|
||||
|
||||
// 创建参数表达式
|
||||
var convertedArgs = parameterTypes.Select((paramType, index) =>
|
||||
Expression.Convert(Expression.ArrayIndex(argsParam, Expression.Constant(index)), paramType)
|
||||
).ToArray();
|
||||
|
||||
|
||||
// 创建方法调用表达式
|
||||
var methodCall = Expression.Call(
|
||||
Expression.Convert(instanceParam, type),
|
||||
methodInfo,
|
||||
convertedArgs
|
||||
);
|
||||
|
||||
// 创建 lambda 表达式
|
||||
var lambda = Expression.Lambda<Func<object, object[], object>>(
|
||||
Expression.Convert(methodCall, typeof(object)),
|
||||
instanceParam,
|
||||
argsParam
|
||||
);
|
||||
//var resule = task.DynamicInvoke((object)[Activator.CreateInstance(type), [new DynamicContext(null)]]);
|
||||
return lambda.Compile();
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// 表达式树构建无参数,有返回值(Task<object>)的方法(触发器)
|
||||
/// </summary>
|
||||
public static Delegate MethodCallerAsync(Type type, MethodInfo methodInfo)
|
||||
{
|
||||
string cacheKey = $"{type.FullName}.{methodInfo.Name}.MethodCallerAsync";
|
||||
return Cache.GetOrAdd(cacheKey, _ => CreateMethodCallerDelegateAsync(type, methodInfo));
|
||||
}
|
||||
/// <summary>
|
||||
/// 表达式树构建无参数,有返回值(Task<object>)的方法(触发器)
|
||||
/// </summary>
|
||||
private static Delegate CreateMethodCallerDelegateAsync(Type type, MethodInfo methodInfo)
|
||||
{
|
||||
var parameter = Expression.Parameter(typeof(object), "instance");
|
||||
var methodCall = Expression.Call(Expression.Convert(parameter, type), methodInfo);
|
||||
var lambda = Expression.Lambda<Func<object, Task<object>>>(
|
||||
Expression.Convert(methodCall, typeof(Task<object>)), parameter);
|
||||
// Func<object, Task<object>>
|
||||
return lambda.Compile();
|
||||
}
|
||||
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// 表达式树构建多个参数,有返回值(Task-object)的方法(触发器)
|
||||
/// </summary>
|
||||
public static Delegate MethodCallerAsync(Type type, MethodInfo method, params Type[] parameterTypes)
|
||||
{
|
||||
|
||||
string cacheKey = $"{type.FullName}.{method.Name}.MethodCallerAsync";
|
||||
return Cache.GetOrAdd(cacheKey, _ => CreateMethodCallerDelegateAsync(type, method, parameterTypes));
|
||||
}
|
||||
/// <summary>
|
||||
/// 表达式树构建多个参数,有返回值(Task<object>)的方法(触发器)
|
||||
/// </summary>
|
||||
private static Delegate CreateMethodCallerDelegateAsync(Type type, MethodInfo methodInfo, Type[] parameterTypes)
|
||||
{
|
||||
var instanceParam = Expression.Parameter(typeof(object), "instance");
|
||||
var argsParam = Expression.Parameter(typeof(object[]), "args");
|
||||
|
||||
// 创建参数表达式
|
||||
var convertedArgs = parameterTypes.Select((paramType, index) =>
|
||||
Expression.Convert(Expression.ArrayIndex(argsParam, Expression.Constant(index)),paramType)
|
||||
).ToArray();
|
||||
|
||||
|
||||
// 创建方法调用表达式
|
||||
var methodCall = Expression.Call(
|
||||
Expression.Convert(instanceParam, type),
|
||||
methodInfo,
|
||||
(Expression[])convertedArgs
|
||||
);
|
||||
|
||||
// 创建 lambda 表达式
|
||||
var lambda = Expression.Lambda<Func<object, object[], Task<FlipflopContext>>>(
|
||||
Expression.Convert(methodCall, typeof(Task<FlipflopContext>)),
|
||||
instanceParam,
|
||||
argsParam
|
||||
);
|
||||
//var resule = task.DynamicInvoke((object)[Activator.CreateInstance(type), [new DynamicContext(null)]]);
|
||||
return lambda.Compile();
|
||||
}
|
||||
|
||||
|
||||
|
||||
#region 单参数
|
||||
|
||||
/// <summary>
|
||||
/// 表达式树构建单参数,无返回值的方法
|
||||
/// </summary>
|
||||
public static Delegate MethodCaller(Type type, string methodName, Type parameterType)
|
||||
{
|
||||
string cacheKey = $"{type.FullName}.{methodName}.MethodCallerWithParam";
|
||||
return Cache.GetOrAdd(cacheKey, _ => CreateMethodCallerDelegate(type, methodName, parameterType));
|
||||
}
|
||||
/// <summary>
|
||||
/// 表达式树构建单参数,无返回值的方法
|
||||
/// </summary>
|
||||
private static Delegate CreateMethodCallerDelegate(Type type, string methodName, Type parameterType)
|
||||
{
|
||||
var parameter = Expression.Parameter(typeof(object), "instance");
|
||||
var argument = Expression.Parameter(typeof(object), "argument");
|
||||
var methodCall = Expression.Call(Expression.Convert(parameter, type),
|
||||
type.GetMethod(methodName, [parameterType])!,
|
||||
Expression.Convert(argument, parameterType));
|
||||
var lambda = Expression.Lambda(methodCall, parameter, argument);
|
||||
return lambda.Compile();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 表达式树构建单参数,有返回值的方法
|
||||
/// </summary>
|
||||
public static Delegate MethodCallerWithResult(Type type, string methodName, Type parameterType, Type returnType)
|
||||
{
|
||||
string cacheKey = $"{type.FullName}.{methodName}.MethodCallerWithResult";
|
||||
return Cache.GetOrAdd(cacheKey, _ => CreateMethodCallerDelegateWithResult(type, methodName, parameterType, returnType));
|
||||
}
|
||||
/// <summary>
|
||||
/// 表达式树构建单参数,有返回值的方法
|
||||
/// </summary>
|
||||
private static Delegate CreateMethodCallerDelegateWithResult(Type type, string methodName, Type parameterType, Type returnType)
|
||||
{
|
||||
var parameter = Expression.Parameter(typeof(object), "instance");
|
||||
var argument = Expression.Parameter(typeof(object), "argument");
|
||||
var methodCall = Expression.Call(Expression.Convert(parameter, type),
|
||||
type.GetMethod(methodName, [parameterType])!,
|
||||
Expression.Convert(argument, parameterType));
|
||||
var lambda = Expression.Lambda(Expression.Convert(methodCall, typeof(object)), parameter, argument);
|
||||
|
||||
|
||||
return lambda.Compile();
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#endregion
|
||||
|
||||
|
||||
#region 泛型表达式反射构建方法(已注释)
|
||||
/*
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// 动态获取属性值
|
||||
/// </summary>
|
||||
/// <typeparam name="T"></typeparam>
|
||||
/// <typeparam name="TProperty"></typeparam>
|
||||
/// <param name="propertyName"></param>
|
||||
/// <returns></returns>
|
||||
public static Func<T, TProperty> PropertyGetter<T, TProperty>(string propertyName)
|
||||
{
|
||||
string cacheKey = $"{typeof(T).FullName}.{propertyName}.Getter";
|
||||
return (Func<T, TProperty>)Cache.GetOrAdd(cacheKey, _ => CreateGetterDelegate<T, TProperty>(propertyName));
|
||||
}
|
||||
|
||||
private static Func<T, TProperty> CreateGetterDelegate<T, TProperty>(string propertyName)
|
||||
{
|
||||
var parameter = Expression.Parameter(typeof(T), "instance");
|
||||
var property = Expression.Property(parameter, propertyName);
|
||||
var lambda = Expression.Lambda<Func<T, TProperty>>(property, parameter);
|
||||
return lambda.Compile();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 动态设置属性值
|
||||
/// </summary>
|
||||
/// <typeparam name="T"></typeparam>
|
||||
/// <typeparam name="TProperty"></typeparam>
|
||||
/// <param name="propertyName"></param>
|
||||
/// <returns></returns>
|
||||
public static Action<T, TProperty> PropertySetter<T, TProperty>(string propertyName)
|
||||
{
|
||||
string cacheKey = $"{typeof(T).FullName}.{propertyName}.Setter";
|
||||
return (Action<T, TProperty>)Cache.GetOrAdd(cacheKey, _ => CreateSetterDelegate<T, TProperty>(propertyName));
|
||||
}
|
||||
|
||||
private static Action<T, TProperty> CreateSetterDelegate<T, TProperty>(string propertyName)
|
||||
{
|
||||
var parameter = Expression.Parameter(typeof(T), "instance");
|
||||
var value = Expression.Parameter(typeof(TProperty), "value");
|
||||
var property = Expression.Property(parameter, propertyName);
|
||||
var assign = Expression.Assign(property, value);
|
||||
var lambda = Expression.Lambda<Action<T, TProperty>>(assign, parameter, value);
|
||||
return lambda.Compile();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 动态获取字段值
|
||||
/// </summary>
|
||||
/// <typeparam name="T"></typeparam>
|
||||
/// <typeparam name="TField"></typeparam>
|
||||
/// <param name="fieldName"></param>
|
||||
/// <returns></returns>
|
||||
public static Func<T, TField> FieldGetter<T, TField>(string fieldName)
|
||||
{
|
||||
string cacheKey = $"{typeof(T).FullName}.{fieldName}.FieldGetter";
|
||||
return (Func<T, TField>)Cache.GetOrAdd(cacheKey, _ => CreateFieldGetterDelegate<T, TField>(fieldName));
|
||||
}
|
||||
|
||||
private static Func<T, TField> CreateFieldGetterDelegate<T, TField>(string fieldName)
|
||||
{
|
||||
var parameter = Expression.Parameter(typeof(T), "instance");
|
||||
var field = Expression.Field(parameter, fieldName);
|
||||
var lambda = Expression.Lambda<Func<T, TField>>(field, parameter);
|
||||
return lambda.Compile();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 动态设置字段值
|
||||
/// </summary>
|
||||
/// <typeparam name="T"></typeparam>
|
||||
/// <typeparam name="TField"></typeparam>
|
||||
/// <param name="fieldName"></param>
|
||||
/// <returns></returns>
|
||||
public static Action<T, TField> FieldSetter<T, TField>(string fieldName)
|
||||
{
|
||||
string cacheKey = $"{typeof(T).FullName}.{fieldName}.FieldSetter";
|
||||
return (Action<T, TField>)Cache.GetOrAdd(cacheKey, _ => CreateFieldSetterDelegate<T, TField>(fieldName));
|
||||
}
|
||||
|
||||
private static Action<T, TField> CreateFieldSetterDelegate<T, TField>(string fieldName)
|
||||
{
|
||||
var parameter = Expression.Parameter(typeof(T), "instance");
|
||||
var value = Expression.Parameter(typeof(TField), "value");
|
||||
var field = Expression.Field(parameter, fieldName);
|
||||
var assign = Expression.Assign(field, value);
|
||||
var lambda = Expression.Lambda<Action<T, TField>>(assign, parameter, value);
|
||||
return lambda.Compile();
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// 动态调用无参数方法
|
||||
/// </summary>
|
||||
/// <typeparam name="T"></typeparam>
|
||||
/// <param name="methodName"></param>
|
||||
/// <returns></returns>
|
||||
public static Action<T> MethodCaller<T>(string methodName)
|
||||
{
|
||||
string cacheKey = $"{typeof(T).FullName}.{methodName}.MethodCaller";
|
||||
return (Action<T>)Cache.GetOrAdd(cacheKey, _ => CreateMethodCallerDelegate<T>(methodName));
|
||||
}
|
||||
|
||||
private static Action<T> CreateMethodCallerDelegate<T>(string methodName)
|
||||
{
|
||||
var parameter = Expression.Parameter(typeof(T), "instance");
|
||||
var methodCall = Expression.Call(parameter, typeof(T).GetMethod(methodName));
|
||||
var lambda = Expression.Lambda<Action<T>>(methodCall, parameter);
|
||||
return lambda.Compile();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 动态调用无参有返回值方法
|
||||
/// </summary>
|
||||
/// <typeparam name="T"></typeparam>
|
||||
/// <typeparam name="TResult"></typeparam>
|
||||
/// <param name="methodName"></param>
|
||||
/// <returns></returns>
|
||||
public static Func<T, TResult> MethodCallerHaveResul<T, TResult>(string methodName)
|
||||
{
|
||||
string cacheKey = $"{typeof(T).FullName}.{methodName}.MethodCaller";
|
||||
return (Func<T, TResult>)Cache.GetOrAdd(cacheKey, _ => CreateMethodCallerDelegateHaveResult<T, TResult>(methodName));
|
||||
}
|
||||
|
||||
private static Func<T, TResult> CreateMethodCallerDelegateHaveResult<T, TResult>(string methodName)
|
||||
{
|
||||
var parameter = Expression.Parameter(typeof(T), "instance");
|
||||
var methodCall = Expression.Call(parameter, typeof(T).GetMethod(methodName));
|
||||
var lambda = Expression.Lambda<Func<T, TResult>>(methodCall, parameter);
|
||||
return lambda.Compile();
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// 动态调用单参数无返回值的方法
|
||||
/// </summary>
|
||||
/// <typeparam name="T"></typeparam>
|
||||
/// <typeparam name="TParam"></typeparam>
|
||||
/// <param name="methodName"></param>
|
||||
/// <returns></returns>
|
||||
public static Action<T, TParam> MethodCaller<T, TParam>(string methodName)
|
||||
{
|
||||
string cacheKey = $"{typeof(T).FullName}.{methodName}.MethodCallerWithParam";
|
||||
return (Action<T, TParam>)Cache.GetOrAdd(cacheKey, _ => CreateMethodCallerDelegate<T, TParam>(methodName));
|
||||
}
|
||||
|
||||
private static Action<T, TParam> CreateMethodCallerDelegate<T, TParam>(string methodName)
|
||||
{
|
||||
var parameter = Expression.Parameter(typeof(T), "instance");
|
||||
var argument = Expression.Parameter(typeof(TParam), "argument");
|
||||
var methodCall = Expression.Call(parameter, typeof(T).GetMethod(methodName), argument);
|
||||
var lambda = Expression.Lambda<Action<T, TParam>>(methodCall, parameter, argument);
|
||||
return lambda.Compile();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 动态调用单参数有返回值的方法
|
||||
/// </summary>
|
||||
/// <typeparam name="T"></typeparam>
|
||||
/// <typeparam name="TParam"></typeparam>
|
||||
/// <typeparam name="TResult"></typeparam>
|
||||
/// <param name="methodName"></param>
|
||||
/// <returns></returns>
|
||||
public static Func<T, TParam, TResult> MethodCallerWithResult<T, TParam, TResult>(string methodName)
|
||||
{
|
||||
string cacheKey = $"{typeof(T).FullName}.{methodName}.MethodCallerWithResult";
|
||||
return (Func<T, TParam, TResult>)Cache.GetOrAdd(cacheKey, _ => CreateMethodCallerDelegate<T, TParam, TResult>(methodName));
|
||||
}
|
||||
|
||||
private static Func<T, TParam, TResult> CreateMethodCallerDelegate<T, TParam, TResult>(string methodName)
|
||||
{
|
||||
var parameter = Expression.Parameter(typeof(T), "instance");
|
||||
var argument = Expression.Parameter(typeof(TParam), "argument");
|
||||
var methodCall = Expression.Call(parameter, typeof(T).GetMethod(methodName), argument);
|
||||
var lambda = Expression.Lambda<Func<T, TParam, TResult>>(methodCall, parameter, argument);
|
||||
return lambda.Compile();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 动态调用多参无返回值的方法
|
||||
/// </summary>
|
||||
/// <typeparam name="T"></typeparam>
|
||||
/// <param name="methodName"></param>
|
||||
/// <param name="parameterTypes"></param>
|
||||
/// <returns></returns>
|
||||
public static Action<T, object[]> MethodCaller<T>(string methodName, params Type[] parameterTypes)
|
||||
{
|
||||
string cacheKey = $"{typeof(T).FullName}.{methodName}.MethodCaller";
|
||||
return (Action<T, object[]>)Cache.GetOrAdd(cacheKey, _ => CreateMethodCallerDelegate<T>(methodName, parameterTypes));
|
||||
}
|
||||
|
||||
private static Action<T, object[]> CreateMethodCallerDelegate<T>(string methodName, Type[] parameterTypes)
|
||||
{
|
||||
var parameter = Expression.Parameter(typeof(T), "instance");
|
||||
var arguments = parameterTypes.Select((type, index) =>
|
||||
Expression.Parameter(typeof(object), $"arg{index}")
|
||||
).ToList();
|
||||
|
||||
var convertedArguments = arguments.Select((arg, index) =>
|
||||
Expression.Convert(arg, parameterTypes[index])
|
||||
).ToList();
|
||||
|
||||
var methodInfo = typeof(T).GetMethod(methodName, parameterTypes);
|
||||
|
||||
if (methodInfo == null)
|
||||
{
|
||||
throw new ArgumentException($"Method '{methodName}' not found in type '{typeof(T).FullName}' with given parameter types.");
|
||||
}
|
||||
|
||||
var methodCall = Expression.Call(parameter, methodInfo, convertedArguments);
|
||||
var lambda = Expression.Lambda<Action<T, object[]>>(methodCall, new[] { parameter }.Concat(arguments));
|
||||
return lambda.Compile();
|
||||
}
|
||||
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// 动态调用多参有返回值的方法
|
||||
/// </summary>
|
||||
/// <typeparam name="T"></typeparam>
|
||||
/// <typeparam name="TResult"></typeparam>
|
||||
/// <param name="methodName"></param>
|
||||
/// <param name="parameterTypes"></param>
|
||||
/// <returns></returns>
|
||||
public static Func<T, object[], TResult> MethodCallerHaveResult<T, TResult>(string methodName, Type[] parameterTypes)
|
||||
{
|
||||
string cacheKey = $"{typeof(T).FullName}.{methodName}.MethodCallerHaveResult";
|
||||
return (Func<T, object[], TResult>)Cache.GetOrAdd(cacheKey, _ => CreateMethodCallerDelegate<T, TResult>(methodName, parameterTypes));
|
||||
}
|
||||
|
||||
private static Func<T, object[], TResult> CreateMethodCallerDelegate<T, TResult>(string methodName, Type[] parameterTypes)
|
||||
{
|
||||
var instanceParam = Expression.Parameter(typeof(T), "instance");
|
||||
var argsParam = Expression.Parameter(typeof(object[]), "args");
|
||||
|
||||
var convertedArgs = new Expression[parameterTypes.Length];
|
||||
for (int i = 0; i < parameterTypes.Length; i++)
|
||||
{
|
||||
var index = Expression.Constant(i);
|
||||
var argType = parameterTypes[i];
|
||||
var arrayIndex = Expression.ArrayIndex(argsParam, index);
|
||||
var convertedArg = Expression.Convert(arrayIndex, argType);
|
||||
convertedArgs[i] = convertedArg;
|
||||
}
|
||||
|
||||
var methodInfo = typeof(T).GetMethod(methodName, parameterTypes);
|
||||
|
||||
if (methodInfo == null)
|
||||
{
|
||||
throw new ArgumentException($"Method '{methodName}' not found in type '{typeof(T).FullName}' with given parameter types.");
|
||||
}
|
||||
|
||||
var methodCall = Expression.Call(instanceParam, methodInfo, convertedArgs);
|
||||
var lambda = Expression.Lambda<Func<T, object[], TResult>>(methodCall, instanceParam, argsParam);
|
||||
return lambda.Compile();
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
*/
|
||||
|
||||
#endregion
|
||||
#region 暂时不删(已注释)
|
||||
/* /// <summary>
|
||||
/// 表达式树构建多个参数,有返回值的方法
|
||||
/// </summary>
|
||||
public static Delegate MethodCallerHaveResult(Type type, string methodName, Type[] parameterTypes)
|
||||
{
|
||||
string cacheKey = $"{type.FullName}.{methodName}.MethodCallerHaveResult";
|
||||
return Cache.GetOrAdd(cacheKey, _ => CreateMethodCallerDelegateHaveResult(type, methodName, parameterTypes));
|
||||
}
|
||||
|
||||
private static Delegate CreateMethodCallerDelegateHaveResult(Type type, string methodName, Type[] parameterTypes)
|
||||
{
|
||||
var instanceParam = Expression.Parameter(typeof(object), "instance");
|
||||
var argsParam = Expression.Parameter(typeof(object[]), "args");
|
||||
var convertedArgs = parameterTypes.Select((paramType, index) =>
|
||||
Expression.Convert(Expression.ArrayIndex(argsParam, Expression.Constant(index)), paramType)
|
||||
).ToArray();
|
||||
var methodCall = Expression.Call(Expression.Convert(instanceParam, type), type.GetMethod(methodName, parameterTypes), convertedArgs);
|
||||
var lambda = Expression.Lambda(Expression.Convert(methodCall, typeof(object)), instanceParam, argsParam);
|
||||
return lambda.Compile();
|
||||
}*/
|
||||
|
||||
|
||||
|
||||
/*/// <summary>
|
||||
/// 表达式反射 构建 无返回值、无参数 的委托
|
||||
/// </summary>
|
||||
/// <param name="type"></param>
|
||||
/// <param name="methodName"></param>
|
||||
/// <param name="parameterTypes"></param>
|
||||
/// <returns></returns>
|
||||
public static Delegate MethodCaller(Type type, string methodName, Type[] parameterTypes)
|
||||
{
|
||||
string cacheKey = $"{type.FullName}.{methodName}.{string.Join(",", parameterTypes.Select(t => t.FullName))}.MethodCaller";
|
||||
return Cache.GetOrAdd(cacheKey, _ => CreateMethodCallerDelegate(type, methodName, parameterTypes));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 表达式反射 构建 无返回值、无参数 的委托
|
||||
/// </summary>
|
||||
/// <param name="type"></param>
|
||||
/// <param name="methodName"></param>
|
||||
/// <param name="parameterTypes"></param>
|
||||
/// <returns></returns>
|
||||
private static Delegate CreateMethodCallerDelegate(Type type, string methodName, Type[] parameterTypes)
|
||||
{
|
||||
var parameter = Expression.Parameter(typeof(object), "instance");
|
||||
var arguments = parameterTypes.Select((paramType, index) => Expression.Parameter(paramType, $"param{index}")).ToArray();
|
||||
var methodCall = Expression.Call(Expression.Convert(parameter, type), type.GetMethod(methodName, parameterTypes), arguments);
|
||||
|
||||
var delegateType = Expression.GetActionType(new[] { typeof(object) }.Concat(parameterTypes).ToArray());
|
||||
var lambda = Expression.Lambda(delegateType, methodCall, new[] { parameter }.Concat(arguments).ToArray());
|
||||
return lambda.Compile();
|
||||
}
|
||||
*/
|
||||
/*public static Delegate MethodCallerHaveResult(Type type, string methodName, Type returnType, Type[] parameterTypes)
|
||||
{
|
||||
string cacheKey = $"{type.FullName}.{methodName}.{string.Join(",", parameterTypes.Select(t => t.FullName))}.MethodCallerHaveResult";
|
||||
return Cache.GetOrAdd(cacheKey, _ => CreateMethodCallerDelegateHaveResult(type, methodName, returnType, parameterTypes));
|
||||
}
|
||||
|
||||
private static Delegate CreateMethodCallerDelegateHaveResult(Type type, string methodName, Type returnType, Type[] parameterTypes)
|
||||
{
|
||||
var parameter = Expression.Parameter(typeof(object), "instance");
|
||||
var arguments = parameterTypes.Select((paramType, index) => Expression.Parameter(paramType, $"param{index}")).ToArray();
|
||||
var methodCall = Expression.Call(Expression.Convert(parameter, type), type.GetMethod(methodName, parameterTypes), arguments);
|
||||
|
||||
var delegateType = Expression.GetFuncType(new[] { typeof(object) }.Concat(parameterTypes).Concat(new[] { typeof(object) }).ToArray());
|
||||
var lambda = Expression.Lambda(delegateType, Expression.Convert(methodCall, typeof(object)), new[] { parameter }.Concat(arguments).ToArray());
|
||||
return lambda.Compile();
|
||||
}
|
||||
|
||||
*/
|
||||
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
80
Library.Core/Flow/Tool/TcsSignal.cs
Normal file
80
Library.Core/Flow/Tool/TcsSignal.cs
Normal file
@@ -0,0 +1,80 @@
|
||||
using System.Collections.Concurrent;
|
||||
|
||||
namespace Serein.Flow.Tool
|
||||
{
|
||||
public class TcsSignalException : Exception
|
||||
{
|
||||
public FfState FfState { get; set; }
|
||||
public TcsSignalException(string? message) : base(message)
|
||||
{
|
||||
FfState = FfState.Cancel;
|
||||
}
|
||||
}
|
||||
|
||||
public class TcsSignal<TSignal> where TSignal : struct, Enum
|
||||
{
|
||||
|
||||
public ConcurrentDictionary<TSignal, Stack<TaskCompletionSource<object>>> TcsEvent { get; } = new();
|
||||
|
||||
// public object tcsObj = new object();
|
||||
|
||||
public bool TriggerSignal<T>(TSignal signal, T state)
|
||||
{
|
||||
if (TcsEvent.TryRemove(signal, out var waitTcss))
|
||||
{
|
||||
while (waitTcss.Count > 0)
|
||||
{
|
||||
|
||||
waitTcss.Pop().SetResult(state);
|
||||
|
||||
}
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
|
||||
|
||||
}
|
||||
|
||||
public TaskCompletionSource<object> CreateTcs(TSignal signal)
|
||||
{
|
||||
|
||||
var tcs = new TaskCompletionSource<object>();
|
||||
TcsEvent.GetOrAdd(signal, _ => new Stack<TaskCompletionSource<object>>()).Push(tcs);
|
||||
return tcs;
|
||||
|
||||
|
||||
|
||||
}
|
||||
//public TaskCompletionSource<object> GetOrCreateTcs(TSignal signal)
|
||||
//{
|
||||
// lock (tcsObj)
|
||||
// {
|
||||
// var tcs = TcsEvent.GetOrAdd(signal, _ => new TaskCompletionSource<object>());
|
||||
// if (tcs.Task.IsCompleted)
|
||||
// {
|
||||
// TcsEvent.TryRemove(signal, out _);
|
||||
// tcs = new TaskCompletionSource<object>();
|
||||
// TcsEvent[signal] = tcs;
|
||||
// }
|
||||
// return tcs;
|
||||
// }
|
||||
//}
|
||||
|
||||
public void CancelTask()
|
||||
{
|
||||
lock(TcsEvent)
|
||||
{
|
||||
|
||||
foreach (var tcss in TcsEvent.Values)
|
||||
{
|
||||
while (tcss.Count > 0)
|
||||
{
|
||||
tcss.Pop().SetException(new TcsSignalException("Task Cancel"));
|
||||
}
|
||||
}
|
||||
TcsEvent.Clear();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user