52 lines
1.8 KiB
C#
52 lines
1.8 KiB
C#
|
|
using System;
|
|||
|
|
using System.Collections.Concurrent;
|
|||
|
|
using System.Reflection;
|
|||
|
|
|
|||
|
|
namespace JiShe.CollectBus.Analyzers.Shared;
|
|||
|
|
|
|||
|
|
public static class SourceEntityAccessorFactory3
|
|||
|
|
{
|
|||
|
|
private static readonly ConcurrentDictionary<Type, object> _accessors = new();
|
|||
|
|
|
|||
|
|
public static ISourceEntityAccessor<T> GetAccessor<T>()
|
|||
|
|
{
|
|||
|
|
return (ISourceEntityAccessor<T>)_accessors.GetOrAdd(typeof(T), t =>
|
|||
|
|
{
|
|||
|
|
// 获取泛型类型定义信息(如果是泛型类型)
|
|||
|
|
var isGeneric = t.IsGenericType;
|
|||
|
|
var genericTypeDef = isGeneric ? t.GetGenericTypeDefinition() : null;
|
|||
|
|
var arity = isGeneric ? genericTypeDef!.GetGenericArguments().Length : 0;
|
|||
|
|
|
|||
|
|
// 构建访问器类名
|
|||
|
|
var typeName = isGeneric
|
|||
|
|
? $"{t.Namespace}.{genericTypeDef!.Name.Split('`')[0]}Accessor`{arity}"
|
|||
|
|
: $"{t.Namespace}.{t.Name}Accessor";
|
|||
|
|
|
|||
|
|
// 尝试从当前程序集加载
|
|||
|
|
var accessorType = Assembly.GetAssembly(t)!.GetType(typeName)
|
|||
|
|
?? throw new InvalidOperationException($"Accessor type {typeName} not found");
|
|||
|
|
|
|||
|
|
// 处理泛型参数
|
|||
|
|
if (isGeneric && accessorType.IsGenericTypeDefinition)
|
|||
|
|
{
|
|||
|
|
accessorType = accessorType.MakeGenericType(t.GetGenericArguments());
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
return Activator.CreateInstance(accessorType)!;
|
|||
|
|
});
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
public static object GetAccessor(Type type)
|
|||
|
|
{
|
|||
|
|
MethodInfo getAccessorMethod = typeof(SourceEntityAccessorFactory)
|
|||
|
|
.GetMethod(
|
|||
|
|
name: nameof(GetAccessor),
|
|||
|
|
bindingAttr: BindingFlags.Public | BindingFlags.Static,
|
|||
|
|
|
|||
|
|
types: Type.EmptyTypes
|
|||
|
|
);
|
|||
|
|
|
|||
|
|
MethodInfo genericMethod = getAccessorMethod.MakeGenericMethod(type);
|
|||
|
|
return genericMethod.Invoke(null, null);
|
|||
|
|
}
|
|||
|
|
}
|