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

时间:2021-09-13 05:07:46

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

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

Database db = DatabaseFactory.CreateDatabase()

我们首先从DatabaseFactory着手

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

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

再来看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中的类,没有源码。

今天的工作先到这里了。