重写了节点的view、viewmodel关系,实现了对画布元素的选取功能,重构了底层依赖,添加了对net .Framework4.6.1以上的Framework类库支持

This commit is contained in:
fengjiayi
2024-09-12 20:32:54 +08:00
parent ec6e09ced1
commit f286fc644a
120 changed files with 91218 additions and 761 deletions

View 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);
}
}
}
}

View 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
}

View 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
}
}

View 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();
}
}
}
}