【发布时间】:2011-05-05 16:45:17
【问题描述】:
我正在编写一些框架式代码,旨在执行大量操作(数十万个),所有这些操作都使用相同的基本组件,但需要从外部源接受特定于操作的配置数据。
现在假设有一个配置库,给定适当的设置名称列表,它知道如何有效地加载这些设置并将它们存储在如下类型中:
public interface IConfiguration
{
dynamic Get(string key);
void Set(string key, dynamic value);
}
我打算做的是实现一些流畅的映射语法,或者只是用如下属性装饰组件类:
public class MyComponent : IActivity
{
[Configuration("Threshold")]
public virtual int Threshold { get; set; }
[Configuration("SomeKey", Persistence = ConfigPersistence.Save)]
public virtual string SomeSetting { get; set; }
}
你得到了图片......希望。需要注意的是,某些属性实际上需要保存回到存储库,因此传统的 DI 库在这里不起作用;即使他们这样做了,它们也是钝器,并非旨在旋转数十万个组件并加载/保存数百万个属性。换句话说,我不认为我在重新发明轮子,但如果有人想说服我不这样做,请随意。
无论如何,我正在考虑两种可能的选项来处理将配置数据“注入”到这些组件实例中:
Plain vanilla Reflection - 扫描配置属性的类型并将成员信息(连同配置键)保存在静态字典中。然后使用反射方法如
PropertyInfo.SetValue和PropertyInfo.GetValue进行注入和提取(因为没有更好的术语)。这类似于大多数 DI 库使用的方法。使用动态代理(例如 Castle)并将拦截器连接到修饰属性,这样它们不会引用私有/自动生成的字段,而是引用
IConfiguration实例(即get方法调用 @987654327 @ 和set方法调用IConfiguration.Set)。这类似于 NHibernate 和其他 ORM 使用的方法。
完整的实现最终可能需要大量的工作,所以我不想在意识到我错过了什么之前走得太错误的道路。
所以我的问题是,这两种方法的优缺点是什么,我需要避免哪些陷阱?我从性能、可维护性、防白痴的角度考虑等。
或者,是否有其他更快的途径来实现这个目标,最好是没有陡峭的学习曲线?
【问题讨论】:
-
嗯,这是我的一个很老的问题,我没有时间写一个完整的答案,但对于其他偶然发现这个问题的人:我最终使用反射进行初始扫描然后编译/缓存使用表达式树构建的委托。我知道它不如 IL weaving 快,但它是对直接反射的重大改进,并且速度足以满足这里的要求。
标签: c# .net reflection interceptor dynamic-proxy