using System.Collections.Concurrent; namespace MS.Microservice.Core.Reflection; /// 某种编译实现的静态开关,类型对象恒为单例,比较引用即可。 public interface IPropertyAccessorStrategy { /// 把类型体对象的属性依次写入目标集合,返回写入后的元素个数。 Func, int> CompilePopulate(Type type); /// 返回该类型全部可读属性的编译访问器,顺序与过滤规则遵循 的契约。 PropertyAccessor[] CreateAccessors(Type type); /// 为属性生成读取委托;属性不可读时返回 。 Func? CompileGetter(System.Reflection.PropertyInfo property); /// 为属性生成写入委托;属性不可写时返回 。 Action? CompileSetter(System.Reflection.PropertyInfo property); /// 按公开无参构造函数生成工厂;没有可用构造函数时返回 。 Func? CompileFactory(Type type); } /// 按(实现,类型)缓存属性的编译访问器,把"元数据发现"限制在每个类型一次。 /// /// 顺序契约:返回的数组按 的元数据顺序排列,同一类型的多次调用顺序稳定 /// (由两个实现的同源测试锁定)。顺序拼接 URL、表头等场景可以直接依赖它。 /// 过滤契约:只包含公开实例、可读、且无索引参数的属性,与逐属性反射的原实现一致。 /// 缓存以实现为键,因此切换 后同一类型会用新实现重新编译,两个实现可以并存对照。 /// Native AOT 与裁剪场景不适用:两种实现都在运行时生成代码。 /// public static class PropertyAccessors { private static readonly ConcurrentDictionary<(IPropertyAccessorStrategy Strategy, Type Type), PropertyAccessor[]> Cache = new(); private static readonly ConcurrentDictionary<(IPropertyAccessorStrategy Strategy, Type Type), Func, int>> PopulateCache = new(); private static readonly ConcurrentDictionary<(IPropertyAccessorStrategy Strategy, Type Type), Func?> FactoryCache = new(); private static volatile IPropertyAccessorStrategy active = new IlPropertyAccessorStrategy(); /// 当前生效的编译实现,默认 IL;切换到表达树实现可逐字节对照两种产物。 public static IPropertyAccessorStrategy Active => active; /// IL 版实现(DynamicMethod + ILGenerator),默认策略。 public static IPropertyAccessorStrategy Il { get; } = new IlPropertyAccessorStrategy(); /// 表达树版实现,作为 IL 的对照与回退。 public static IPropertyAccessorStrategy Expression { get; } = new ExpressionPropertyAccessorStrategy(); /// 切换编译实现;下一次取用同一类型时会用新实现重新编译并单独缓存。 public static void Use(IPropertyAccessorStrategy strategy) { ArgumentNullException.ThrowIfNull(strategy); active = strategy; } /// 返回该类型的属性访问器,顺序与过滤规则见类型注释。 public static PropertyAccessor[] Get(Type type) { ArgumentNullException.ThrowIfNull(type); var strategy = active; if (Cache.TryGetValue((strategy, type), out var accessors)) return accessors; return Cache.GetOrAdd((strategy, type), static key => key.Strategy.CreateAccessors(key.Type)); } /// 返回把该类型体写入目标集合的委托,返回值为写入后的元素个数。 public static Func, int> Materializer(Type type) { ArgumentNullException.ThrowIfNull(type); var strategy = active; if (PopulateCache.TryGetValue((strategy, type), out var populate)) return populate; return PopulateCache.GetOrAdd((strategy, type), static key => key.Strategy.CompilePopulate(key.Type)); } /// 返回通过公开无参构造函数创建实例的委托;该类型没有可用构造函数时返回 。 public static Func? Factory(Type type) { ArgumentNullException.ThrowIfNull(type); var strategy = active; if (FactoryCache.TryGetValue((strategy, type), out var factory)) return factory; return FactoryCache.GetOrAdd((strategy, type), static key => key.Strategy.CompileFactory(key.Type)); } }