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的功能分解开,也许会更容易理解和修改。

  • 相关阅读:
    go语言从零学起(三) -- chat实现的思考
    go语言从零学起(二)--list循环删除元素(转载)
    go语言从零学起(一) -- 文档教程篇
    Spring框架事务支持模型的优势
    Thymeleaf
    社保到底是多交好,还是少交好?
    使用静态工厂方法而不是构造器
    EJB、RMI、XMLRPC、Hessian、Thrift 、Protobuf
    MySQL存储过程
    MySQL常用功能语句分类总结
  • 原文地址:https://www.cnblogs.com/HCOONa/p/1525555.html
Copyright © 2011-2022 走看看