微软企业库源码解析——DAAB(四)DatabaseFactory小结

来源:互联网 发布:数据挖掘算法视频教程 编辑:程序博客网 时间:2024/06/17 14:56

经过三章的痛苦的源码解读过程,让我们来回顾一下DatabaseFactory是如何创建出正确的Database类的。 首先,给出MSDN中给出的DAAB的设计结构图 然后,让我们来重温一下DatabaseFactory的创建过程 首先,DatabaseFactory将创建工作交给了新建的DatabaseProviderFactory类。然后DatabaseProviderFactory,实际上是他的父类NameTypeFactoryBase将创建的工作交给了EnterpriseLibraryFactory。EnterpriseLibraryFactory创建了一个StagedStrategyChain,这个Chain中包含了ConfigurationNameMappingStrategy,LocatorLookupStrategy,ConfiguredObjectStrategy,InstrumentationStrategy四个Strategy。EnterpriseLibraryFactory还创建了两个Policy:ConfigurationObjectPolicy和ReflectionCachePolicy。其中ConfigurationObjectPolicy是用来读取配置文件的,ReflectionCachePolicy是使用反射获取某个类的某个Attribute,并将其缓存起来的。接下来,EnterpriseLibraryFactory将工作交给了ObjectBuilder2。 然后ObjectBuilder2调用了StagedStrategyChain中的Strategy。首先,由ConfigurationNameMappingStrategy调用ReflectionCachePolicy获得了Database类的Attribute所指示的ConfigurationNameMapper:DatabaseMapper。接着,ConfigurationNameMappingStrategy调用了DatabaseMapper的Mapper方法,通过ConfigurationObjectPolicy提供的ConfigurationSource读取了配置源中的DefaultDatabase,并替换了BuildContext中的BuildKey(原来是null,如果用的是DatabaseFactory的CreateDatabase(string name)就不用这一步了)。 接下来LocatorLookupStrategy在这里没有起到任何作用。 然后ConfiguredObjectStrategy创建了由配置文件确定的某个Database实例(这里指的是SqlDatabase,OracleDatabase等,以下不再赘述)。这里的过程是,首先通过ReflectionCachePolicy获得了Database类中的CustomFactory标签(Attribute)并创建了DatabaseCustomFactory类,然后调用了DatabaseCustomFactory的CreateObject方法。该方法通过ConfigurationNameMappingStrategy获得了ConnectionStringSettings,DbProviderMapping。然后通过DbProviderMapping得到了相应的Database,并且通过ReflectionCachePolicy获得了该Database的DatabaseAssemblerAttribute,并且创建了该DatabaseAssembler(如SqlDatabaseAssembler),然后,调用了该DatabaseAssembler的Assemble方法创建了相应的Database。 最后InstrumentationStrategy根据配置文件决定是否附加Database的PerformanceCounters,EventLogging,Wmi。如果没有配置过Instrumentation配置节的话,就不附加。否则,调用Database的GetInstrumentationEventProvider方法得到DataInstrumentationProvider。然后调用InstrumentationAttacherFactory的CreateBinder方法。该方法通过ConfigurationReflectionCache得到了DataInstrumentationProvider的InstrumentationListenerAttribute,然后用其DataInstrumentationListener和DataInstrumentationListenerBinder作为参数创建了ExplicitInstrumentationAttacher,最后,调用了ExplicitInstrumentationAttacher的Bind方法,对DataInstrumentationListener和DataInstrumentationProvider进行了绑定。而这个DataInstrumentationProvider是每个Database类在构造函数中创建的。从而完成了对Database的绑定。 这样,我们就可以分析出扩展DAAB的方法。首先,创建一个新的Database类,比如说MySqlDatabase,该类必须继承自Database。然后,创建一个用来创建该类的MySqlDatabaseAssembler类,该类必须实现IDatabaseAssembler接口。然后为MySqlDatabase添加Attribute:[DatabaseAssembler(typeof(MySqlDatabaseAssembler))]。 使用的时候只需在微软企业库配置工具中添加相应的ConnectionString,并且设置好正确的ProviderName。然后添加Custom Provider Mappings。 就大功告成了。 分析DatabaseFactory的源代码,ObjectBuilder的使用自定义的StagedStrategyChain进行对象的创建、装配、附加设置,以及使用Policies对Strategy提供支持使我受益良多。同时ConfigurationSource这种封装,屏蔽了不同ConfigurationSource带来的变化,以及使用XXXConfigurationView这种方式,提供不同模块对设置的不同视图的强类型化的读取,也令我获益匪浅。同时,ReflectionCachePolicy的巧妙设计,也给了我很大的启发。同时,还学会了如何运用Attribute。 另外,我还认为ReflectionCachePolicy设计的过于复杂,如果能将Cache和Reflection的功能分解开,也许会更容易理解和修改。