zoukankan      html  css  js  c++  java
  • 微软企业库源码解析——DAAB(四)DatabaseFactory小结

    经过三章的痛苦的源码解读过程,让我们来回顾一下DatabaseFactory是如何创建出正确的Database类的。

    首先,给出MSDN中给出的DAAB的设计结构图

    DAAB

    然后,让我们来重温一下DatabaseFactory的创建过程

    首先,DatabaseFactory将创建工作交给了新建的DatabaseProviderFactory类。然后DatabaseProviderFactory,实际上是他的父类NameTypeFactoryBase<Database>将创建的工作交给了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。

    image

    就大功告成了。

    分析DatabaseFactory的源代码,ObjectBuilder的使用自定义的StagedStrategyChain进行对象的创建、装配、附加设置,以及使用Policies对Strategy提供支持使我受益良多。同时ConfigurationSource这种封装,屏蔽了不同ConfigurationSource带来的变化,以及使用XXXConfigurationView这种方式,提供不同模块对设置的不同视图的强类型化的读取,也令我获益匪浅。同时,ReflectionCachePolicy的巧妙设计,也给了我很大的启发。同时,还学会了如何运用Attribute。

    另外,我还认为ReflectionCachePolicy设计的过于复杂,如果能将Cache和Reflection的功能分解开,也许会更容易理解和修改。

  • 相关阅读:
    CF575A Fibonotci [线段树+矩阵快速幂]
    P3768 简单的数学题 [杜教筛,莫比乌斯反演]
    2-SAT 学习笔记
    CF776D The Door Problem [2sat]
    KD-Tree 学习笔记
    Mybatis入门笔记(2)——基于代理Dao实现CRUD
    Mybatis入门笔记(1)——基于原始dao实现CRUD
    mybatis入门看这一篇就够了
    使用JDBC程序的问题总结
    关于递归你知道多少?
  • 原文地址:https://www.cnblogs.com/HCOONa/p/1525555.html
Copyright © 2011-2022 走看看