• 微软企业库源码解析——DAAB(一)DatabaseFactory


    首先从最常用的数据获取块开始下手。

    我们每次使用数据获取块首先做的就是得到一个Database

    Database db = DatabaseFactory.CreateDatabase()

    我们首先从DatabaseFactory着手

    从名字上即可以猜测,DatabaseFactory是工厂模式的应用,用来创建一个恰当的Database。我们知道DAAB是兼容多种数据库的(MSSQL,Oracle等),因此所创建的Database应该是特异化的Database,比如SqlDatabase,从源代码的结构上看也是这样的。

    image

    再来看DatabaseFactory的代码

    public static class DatabaseFactory

    DatabaseFactory是一个静态类,其中只含有静态方法

    public static Database CreateDatabase();
    public static Database CreateDatabase(string name);
    private static void TryLogConfigurationError(ConfigurationErrorsException configurationException, string instanceName)

    我们关注的是CreateDatabase方法,这两个方法差不多,不过一个是得到默认Database一个是得到指定的Database

       1: public static Database CreateDatabase()
       2: {
       3:     try
       4:     {
       5:         DatabaseProviderFactory factory = new DatabaseProviderFactory(ConfigurationSourceFactory.Create());
       6:         return factory.CreateDefault();
       7:     }
       8:     catch (ConfigurationErrorsException configurationException)
       9:     {
      10:         TryLogConfigurationError(configurationException, "default");
      11:  
      12:         throw;
      13:     }
      14: }

    从上面的代码我们可以发现DatabaseFactory是从DatabaseProviderFactory获得了Database并返回的,同时尝试把发生的错误记录下来,然后异常又被再次抛出了。

    对于异常的处理并不是我们关心的,我们继续去看DatabaseProviderFactory。

       1: public class DatabaseProviderFactory : NameTypeFactoryBase<Database>
       2: {
       3:     /// <summary>
       4:     /// <para>Initializes a new instance of the <see cref="DatabaseProviderFactory"/> class 
       5:     /// with the default configuration source.</para>
       6:     /// </summary>
       7:     protected DatabaseProviderFactory()
       8:         : base()
       9:     {
      10:     }
      11:  
      12:     /// <summary>
      13:     /// <para>Initializes a new instance of the <see cref="DatabaseProviderFactory"/> class 
      14:     /// with the given configuration source.</para>
      15:     /// </summary>
      16:     /// <param name="configurationSource">The source for configuration information.</param>
      17:     public DatabaseProviderFactory(IConfigurationSource configurationSource)
      18:         : base(configurationSource)
      19:     {}
      20:  
      21: }

    可以知道,DatabaseFactory用ConfigurationSourceFactory创建的一个配置源装配了DatabaseProviderFactory。看来重点在NameTypeFactoryBase上。

    我们来看NameTypeFactoryBase。

       1: /// <summary>
       2: /// Base class for instance factories.
       3: /// </summary>
       4: /// <remarks>
       5: /// This class is used to create instances of types compatible with <typeparamref name="T"/> described 
       6: /// by a configuration source.
       7: /// </remarks>
       8: public class NameTypeFactoryBase<T>
       9: {
      10:     private IConfigurationSource configurationSource;
      11:  
      12:     /// <summary>
      13:     /// Initializes a new instance of the <see cref="NameTypeFactoryBase{T}"/> class with the default configuration source.
      14:     /// </summary>
      15:     protected NameTypeFactoryBase()
      16:         : this(ConfigurationSourceFactory.Create())
      17:     {
      18:     }
      19:  
      20:     /// <summary>
      21:     /// Initializes a new instance of the <see cref="NameTypeFactoryBase{T}"/> class with a configuration source.
      22:     /// </summary>
      23:     /// <param name="configurationSource">The configuration source to use.</param>
      24:     protected NameTypeFactoryBase(IConfigurationSource configurationSource)
      25:     {
      26:         this.configurationSource = configurationSource;
      27:     }
      28:  
      29:     /// <summary>
      30:     /// Returns a new instance of <typeparamref name="T"/> based on the default instance configuration.
      31:     /// </summary>
      32:     /// <returns>
      33:     /// A new instance of <typeparamref name="T"/>.
      34:     /// </returns>
      35:     public T CreateDefault()
      36:     {
      37:         return EnterpriseLibraryFactory.BuildUp<T>(configurationSource);
      38:     }
      39:  
      40:     /// <summary>
      41:     /// Returns an new instance of <typeparamref name="T"/> based on the configuration for <paramref name="name"/>.
      42:     /// </summary>
      43:     /// <param name="name">The name of the required instance.</param>
      44:     /// <returns>
      45:     /// A new instance of <typeparamref name="T"/>.
      46:     /// </returns>
      47:     public T Create(string name)
      48:     {
      49:         return EnterpriseLibraryFactory.BuildUp<T>(name, configurationSource);
      50:     }
      51: }

    回忆DatabaseFactory类,在创建了一个DatabaseProviderFactory后即调用了其Create或CreateDefault方法,这两个方法都是由NameTypeFactoryBase<Database>继承的。从这里可以看出,NameTypeFactoryBase用EnterpriseLibraryFactory从配置源读取配置并装配了Database类。

    我们继续挖掘到EnterpriseLibraryFactory类。

    public static class EnterpriseLibraryFactory

    这也是一个静态类。这个类代码比较多,我就拣几段重要的贴上来。

       1: static EnterpriseLibraryFactory()
       2: {
       3:     builder = new Builder();
       4:     StagedStrategyChain<BuilderStage> stagedStrategyChain = new StagedStrategyChain<BuilderStage>();
       5:     stagedStrategyChain.AddNew<ConfigurationNameMappingStrategy>(BuilderStage.PreCreation);
       6:     stagedStrategyChain.AddNew<LocatorLookupStrategy>(BuilderStage.PreCreation);
       7:     stagedStrategyChain.AddNew<ConfiguredObjectStrategy>(BuilderStage.PreCreation);
       8:     stagedStrategyChain.AddNew<InstrumentationStrategy>(BuilderStage.PostInitialization);
       9:     strategyChain = stagedStrategyChain.MakeStrategyChain();
      10: }
       1: public static T BuildUp<T>(IConfigurationSource configurationSource)
       2: {
       3:     return BuildUp<T>(null, null, configurationSource);
       4: }
       5:  
       6: public static T BuildUp<T>(IReadWriteLocator locator,
       7:                            ILifetimeContainer lifetimeContainer,
       8:                            IConfigurationSource configurationSource)
       9: {
      10:     if (configurationSource == null)
      11:         throw new ArgumentNullException("configurationSource");
      12:  
      13:     try
      14:     {
      15:         return GetObjectBuilder()
      16:             .BuildUp<T>(locator,
      17:                         lifetimeContainer,
      18:                         GetPolicies(configurationSource),
      19:                         strategyChain,
      20:                         NamedTypeBuildKey.Make<T>(),
      21:                         null);
      22:  
      23:     }
      24:     catch (BuildFailedException e)
      25:     {
      26:         // look for the wrapped ConfigurationErrorsException, if any, and throw it
      27:         ConfigurationErrorsException cee = GetConfigurationErrorsException(e);
      28:         if (cee != null)
      29:         {
      30:             throw cee;
      31:         }
      32:  
      33:         // unknown exception, bubble it up
      34:         throw;
      35:     }
      36: }

       1: private static PolicyList GetPolicies(IConfigurationSource configurationSource)
       2: {
       3:     PolicyList policyList = new PolicyList();
       4:     policyList.Set<IConfigurationObjectPolicy>(new ConfigurationObjectPolicy(configurationSource),
       5:                                                typeof(IConfigurationSource));
       6:     policyList.Set<IReflectionCachePolicy>(new ReflectionCachePolicy(reflectionCache),
       7:                                            typeof(IReflectionCachePolicy));
       8:  
       9:     return policyList;
      10: }
      11:  
      12: private static IBuilder GetObjectBuilder()
      13: {
      14:     return builder;
      15: }
      16:  
      17: private static IConfigurationSource ConfigurationSource
      18: {
      19:     get { return ConfigurationSourceFactory.Create(); }
      20: }

    熟悉Unity的朋友应该能猜到,大概是按照StrategyChain对Database进行了装配。

    现在关键就在builder上了,可是Builder是ObjectBuilder2中的类,没有源码。

    今天的工作先到这里了。

  • 相关阅读:
    【PL/SQL练习】显式游标
    【PL/SQL练习】控制结构
    【PL/SQL练习】游标cursor :oracle 在执行sql语句时,为sql语句所分配的一个私有的内存区域
    【PL/SQL练习】DML语句的处理(可以处理多行数据)
    【PL/SQL练习】复合变量: 可以一次传递多个值到变量中。
    【PL/SQL练习】基本的PL/SQL语句
    【小错误】监听
    【考试】用户管理
    【考试】简单的sql语句
    织梦自定义表单地区联动类型不可用的解决办法
  • 原文地址:https://www.cnblogs.com/HCOONa/p/1522675.html
Copyright © 2020-2023  润新知