我正在研究一些用于执行大量操作(数十万)的框架代码,所有操作都使用相同的基本组件,但需要接受来自外部源的特定于操作的配置数据。
假设有一个配置存储库,在给定适当的设置名称列表的情况下,它知道如何有效地加载这些设置并将它们存储在如下类型中:
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
方法调用IConfiguration.Get
和set
方法调用IConfiguration.Set
)。这类似于NHibernate和其他ORM使用的方法。
完整的实施可能最终会成为一项相当多的工作,所以我不想在错误的路径上走 ,然后才意识到我错过了什么。
所以我的问题是,这两种方法的优点/缺点是什么?我需要避免哪些陷阱?我在广泛的性能,可维护性,白痴性方面进行思考等等。
或者,或者,是否还有其他更快捷的途径来实现这一目标,最好是没有陡峭的学习曲线?
答案 0 :(得分:0)
动态代理是更好的方法。定义一个“配置”拦截器,它将配置中的值注入到组件中(最好是懒惰)。使用动态代理,我还会为代理组件实现一个通用的IDisposable接口,这样当对象被处理或GC时,它将根据属性中设置的Peristence标志持久保存配置值。