(IReadWriteLocatorlocator,ILifetimeContainerlifetime,IPolicyListpolicies,IStrategyChainstrategies,objectbuildKey,objectexisting)2:{3:return(TT" />

欧美三区_成人在线免费观看视频_欧美极品少妇xxxxⅹ免费视频_a级毛片免费播放_鲁一鲁中文字幕久久_亚洲一级特黄

微軟企業庫源碼解析——DAAB(二)DatabaseFact

系統 2175 0

其實跟蹤到這里我就已經崩潰了,不過為了讓問題水落石出,我們祭出Reflactor繼續追蹤下去。

        
             1:
        
        
          public
        
         TTypeToBuild BuildUp<TTypeToBuild>(IReadWriteLocator locator, ILifetimeContainer lifetime, IPolicyList policies, IStrategyChain strategies, 
        
          object
        
         buildKey, 
        
          object
        
         existing)
      
        
             2:
        
         {
      
        
             3:
        
        
          return
        
         (TTypeToBuild) 
        
          this
        
        .BuildUp(locator, lifetime, policies, strategies, buildKey, existing);
      
        
             4:
        
         }
      
        
             5:
        
        ? 
      
        
             6:
        
        
          public
        
        
          object
        
         BuildUp(IReadWriteLocator locator, ILifetimeContainer lifetime, IPolicyList policies, IStrategyChain strategies, 
        
          object
        
         buildKey, 
        
          object
        
         existing)
      
        
             7:
        
         {
      
        
             8:
        
             Guard.ArgumentNotNull(strategies, 
        
          "strategies"
        
        );
      
        
             9:
        
             BuilderContext context = 
        
          new
        
         BuilderContext(strategies, locator, lifetime, policies, buildKey, existing);
      
        
            10:
        
        
          return
        
         strategies.ExecuteBuildUp(context);
      
        
            11:
        
         }
      

這里面的Guard是用來檢測各種參數的,其中提供了類似于ArgumentNotNull之類的一系列方法,也是比較常用的,將參數檢測集中起來的方法,值得大家學習。

可以看到,Builder用了StrategyChain進行的裝配。所以,我們又得返回去看看StrategyChain里面都有什么東西。

找到EnterpriseLibraryFactory的構造函數,發現StrategyChain是這么出來的

        
             1:
        
         StagedStrategyChain<BuilderStage> stagedStrategyChain = 
        
          new
        
         StagedStrategyChain<BuilderStage>();
      
        
             2:
        
         stagedStrategyChain.AddNew<ConfigurationNameMappingStrategy>(BuilderStage.PreCreation);
      
        
             3:
        
         stagedStrategyChain.AddNew<LocatorLookupStrategy>(BuilderStage.PreCreation);
      
        
             4:
        
         stagedStrategyChain.AddNew<ConfiguredObjectStrategy>(BuilderStage.PreCreation);
      
        
             5:
        
         stagedStrategyChain.AddNew<InstrumentationStrategy>(BuilderStage.PostInitialization);
      
        
             6:
        
         strategyChain = stagedStrategyChain.MakeStrategyChain();
      

據我猜測,BuilderStage應該是說明在何時這個策略參與對象的裝配的。

我們從第一個Strategy開始看,即ConfigurationNameMappingStrategy。

        
             1:
        
        
          /// <summary>
        
      
        
             2:
        
        
          /// Implementation of <see cref="IBuilderStrategy"/> which maps null instance names into a different name.
        
      
        
             3:
        
        
          /// </summary>
        
      
        
             4:
        
        
          /// <remarks>
        
      
        
             5:
        
        
          /// The strategy is used to deal with default names.
        
      
        
             6:
        
        
          /// </remarks>
        
      
        
             7:
        
        
          /// <seealso cref="ConfigurationNameMapperAttribute"/>
        
      
        
             8:
        
        
          /// <seealso cref="IConfigurationNameMapper"/>
        
      
        
             9:
        
        
          public
        
        
          class
        
         ConfigurationNameMappingStrategy : EnterpriseLibraryBuilderStrategy
      
        
            10:
        
         {
      
        
            11:
        
        
          /// <summary>
        
      
        
            12:
        
        
          /// Override of <see cref="IBuilderStrategy.PreBuildUp"/>. Updates the instance name using a name mapper associated to type 
        
      
        
            13:
        
        
          /// to build so later strategies in the build chain will use the updated instance name.
        
      
        
            14:
        
        
          /// </summary>
        
      
        
            15:
        
        
          /// <remarks>
        
      
        
            16:
        
        
          /// Will only update the instance name if it is <see langword="null"/>.
        
      
        
            17:
        
        
          /// </remarks>
        
      
        
            18:
        
        
          /// <param name="context">The <see cref="IBuilderContext"/> that represents the current building process.</param>
        
      
        
            19:
        
        
          /// <exception cref="System.Configuration.ConfigurationErrorsException"> when the configuration required to do the mapping is not present or is 
        
      
        
            20:
        
        
          /// invalid in the configuration source.</exception>
        
      
        
            21:
        
        
          public
        
        
          override
        
        
          void
        
         PreBuildUp(IBuilderContext context)
      
        
            22:
        
             {
      
        
            23:
        
        
          base
        
        .PreBuildUp(context);
      
        
            24:
        
        ? 
      
        
            25:
        
                 NamedTypeBuildKey key = (NamedTypeBuildKey) context.BuildKey;
      
        
            26:
        
        ? 
      
        
            27:
        
        
          if
        
         (key.Name == 
        
          null
        
        )
      
        
            28:
        
                 {
      
        
            29:
        
                     ConfigurationReflectionCache reflectionCache = GetReflectionCache(context);
      
        
            30:
        
        ? 
      
        
            31:
        
                     IConfigurationNameMapper mapper = reflectionCache.GetConfigurationNameMapper(key.Type);
      
        
            32:
        
        
          if
        
         (mapper != 
        
          null
        
        )
      
        
            33:
        
                     {
      
        
            34:
        
                         context.BuildKey = 
        
          new
        
         NamedTypeBuildKey(key.Type, mapper.MapName(
        
          null
        
        , GetConfigurationSource(context)));
      
        
            35:
        
                     }
      
        
            36:
        
                 }
      
        
            37:
        
             }
      
        
            38:
        
         }
      

從注釋我們可以看出,這個策略是為了將默認名稱取出來并替換null名稱的。剛剛我們CreateDatabase的時候如果不加上實例名的話,傳遞的就是null。這個策略就是將這個null的實例名替換成被標記為Default的實例名,以便下面的裝配工作順利進行。

我們看到PreBuildUp方法是override的,同時還調用了base.PreBuildUp。在ConfigurationNameMappingStrategy的父類EnterpriseLibraryBuilderStrategy中沒有覆蓋PreBuildUp方法。我用Reflactor查看了EnterpriseLibraryBuilderStrategy的父類BuilderStrategy,看到了BuilderStrategy的四個方法

        
             1:
        
        
          public
        
        
          virtual
        
        
          void
        
         PostBuildUp(IBuilderContext context);
      
        
             2:
        
        
          public
        
        
          virtual
        
        
          void
        
         PostTearDown(IBuilderContext context);
      
        
             3:
        
        
          public
        
        
          virtual
        
        
          void
        
         PreBuildUp(IBuilderContext context);
      
        
             4:
        
        
          public
        
        
          virtual
        
        
          void
        
         PreTearDown(IBuilderContext context);
      

都是空方法

NamedTypeBuildKey key實際上就是在EnterpriseLibraryFactory中調用BuildUp時傳遞的參數NamedTypeBuildKey.Make<T>(),而這個方法得到的是NamedTypeBuildKey(typeof(T))。

GetReflectionCache方法是在其父類EnterpriseLibraryBuilderStrategy中定義的

        
             1:
        
        
          protected
        
        
          static
        
         ConfigurationReflectionCache GetReflectionCache(IBuilderContext context)
      
        
             2:
        
         {
      
        
             3:
        
             IReflectionCachePolicy policy
      
        
             4:
        
                 = context.Policies.Get<IReflectionCachePolicy>(
        
          typeof
        
        (IReflectionCachePolicy));
      
        
             5:
        
        ? 
      
        
             6:
        
        
          if
        
         (policy == 
        
          null
        
        )
      
        
             7:
        
        
          return
        
        
          new
        
         ConfigurationReflectionCache();
      
        
             8:
        
        
          else
        
      
        
             9:
        
        
          return
        
         policy.ReflectionCache;
      
        
            10:
        
         }
      

reflectionCache.GetConfigurationNameMapper(key.Type)這里經過了一系列復雜的變化后得到了Database標記中包含的Attribute中指定的ConfigurationNameMapper:DatabaseMapper。這里,我們不用太擔心反射的性能,因為微軟企業庫對反射后的結果等都進行了緩存,大大提高了效率,所以,我們完全可以在需要時隨時創建Database實例。

再來看mapper.MapName

        
             1:
        
        
          /// <summary>
        
      
        
             2:
        
        
          /// This method supports the Enterprise Library infrastructure and is not intended to be used directly from your code.
        
      
        
             3:
        
        
          /// Returns the default database name from the configuration in the <paramref name="configSource"/>, if the
        
      
        
             4:
        
        
          /// value for <paramref name="name"/> is <see langword="null"/> (<b>Nothing</b> in Visual Basic).
        
      
        
             5:
        
        
          /// </summary>
        
      
        
             6:
        
        
          /// <param name="name">The current name.</param>
        
      
        
             7:
        
        
          /// <param name="configSource">The source for configuration information.</param>
        
      
        
             8:
        
        
          /// <returns>The default database name if <paramref name="name"/> is <see langword="null"/> (<b>Nothing</b> in Visual Basic),
        
      
        
             9:
        
        
          /// otherwise the original value for <b>name</b>.</returns>
        
      
        
            10:
        
        
          public
        
        
          string
        
         MapName(
        
          string
        
         name, IConfigurationSource configSource)
      
        
            11:
        
         {
      
        
            12:
        
        
          if
        
         (name != 
        
          null
        
        )
      
        
            13:
        
        
          return
        
         name;
      
        
            14:
        
        ? 
      
        
            15:
        
        
          return
        
        
          new
        
         DatabaseConfigurationView(configSource).DefaultName;
      
        
            16:
        
         }
      

繼續跟蹤到DatabaseConfigurationView

        
             1:
        
        
          /// <summary>
        
      
        
             2:
        
        
          /// <para>Gets the <see cref="DatabaseSettings"/> configuration data.</para>
        
      
        
             3:
        
        
          /// </summary>
        
      
        
             4:
        
        
          /// <returns>
        
      
        
             5:
        
        
          /// <para>The <see cref="DatabaseSettings"/> configuration data.</para>
        
      
        
             6:
        
        
          /// </returns>
        
      
        
             7:
        
        
          public
        
         DatabaseSettings DatabaseSettings
      
        
             8:
        
         {
      
        
             9:
        
             get { 
        
          return
        
         (DatabaseSettings)configurationSource.GetSection(DatabaseSettings.SectionName); }
      
        
            10:
        
         }
      
        
            11:
        
        ? 
      
        
            12:
        
        
          /// <summary>
        
      
        
            13:
        
        
          /// <para>Gets the name of the default configured <see cref="Database"/>.</para>
        
      
        
            14:
        
        
          /// </summary>
        
      
        
            15:
        
        
          /// <returns>
        
      
        
            16:
        
        
          /// <para>The name of the default configured <see cref="Database"/>.</para>
        
      
        
            17:
        
        
          /// </returns>
        
      
        
            18:
        
        
          public
        
        
          string
        
         DefaultName
      
        
            19:
        
         {
      
        
            20:
        
             get
      
        
            21:
        
             {
      
        
            22:
        
                 DatabaseSettings settings = 
        
          this
        
        .DatabaseSettings;
      
        
            23:
        
        
          string
        
         databaseName = settings != 
        
          null
        
         ? settings.DefaultDatabase : 
        
          null
        
        ;
      
        
            24:
        
        
          return
        
         databaseName;
      
        
            25:
        
             }
      
        
            26:
        
         }
      

這里的configurationSource就是一開始在DatabaseFactory中ConfigurationSourceFactory.Create()得到的,后來經過各種傳遞用在這里了。

接下來我們只好跑到ConfigurationSourceFactory中看看是怎么回事了。

        
             1:
        
        
          /// <summary>
        
      
        
             2:
        
        
          /// Creates a new configuration sources based on the default configuration information from the 
        
      
        
             3:
        
        
          /// application's default configuration file.
        
      
        
             4:
        
        
          /// </summary>
        
      
        
             5:
        
        
          /// <returns>The new configuration source instance described as the default in the configuration file,
        
      
        
             6:
        
        
          /// or a new instance of <see cref="SystemConfigurationSource"/> if the is no configuration sources configuration.</returns>
        
      
        
             7:
        
        
          /// <exception cref="ConfigurationSourceSection">when there is a configuration section but it does not define
        
      
        
             8:
        
        
          /// a default configurtion source, or when the configuration for the defined default configuration source is not found.</exception>
        
      
        
             9:
        
        
          public
        
        
          static
        
         IConfigurationSource Create()
      
        
            10:
        
         {
      
        
            11:
        
             ConfigurationSourceSection configurationSourceSection
      
        
            12:
        
                 = ConfigurationSourceSection.GetConfigurationSourceSection();
      
        
            13:
        
        ? 
      
        
            14:
        
        
          if
        
         (configurationSourceSection != 
        
          null
        
        )
      
        
            15:
        
             {
      
        
            16:
        
        
          string
        
         systemSourceName = configurationSourceSection.SelectedSource;
      
        
            17:
        
        
          if
        
         (!
        
          string
        
        .IsNullOrEmpty(systemSourceName))
      
        
            18:
        
                 {
      
        
            19:
        
        
          return
        
         Create(systemSourceName);
      
        
            20:
        
                 }
      
        
            21:
        
        
          else
        
      
        
            22:
        
                 {
      
        
            23:
        
        
          throw
        
        
          new
        
         ConfigurationErrorsException(Resources.ExceptionSystemSourceNotDefined);
      
        
            24:
        
                 }
      
        
            25:
        
             }
      
        
            26:
        
        ? 
      
        
            27:
        
        
          return
        
        
          new
        
         SystemConfigurationSource();
      
        
            28:
        
         }
      

接下來先得看看這句

      ConfigurationSourceSection configurationSourceSection = ConfigurationSourceSection.GetConfigurationSourceSection();
    

這句得到的configurationSourceSection如果是null的話,就直接返回了SystemConfigurationSource

      
        /// <summary>
      
      
/// Configuration section for the configuration sources.
/// </summary>
/// <remarks>
/// This configuration must reside in the application's default configuration file.
/// </remarks>
public class ConfigurationSourceSection : SerializableConfigurationSection
{
private const string selectedSourceProperty = "selectedSource" ;
private const string sourcesProperty = "sources" ;

/// <summary>
/// This field supports the Enterprise Library infrastructure and is not intended to be used directly from your code.
/// </summary>
public const string SectionName = "enterpriseLibrary.ConfigurationSource" ;

/// <summary>
/// Returns the <see cref="ConfigurationSourceSection"/> from the application's default configuration file.
/// </summary>
/// <returns>The section from the configuration file, or <see langword="null"/> (<b>Nothing</b> in Visual Basic) if the section is not present in the configuration file.</returns>
public static ConfigurationSourceSection GetConfigurationSourceSection()
{
return (ConfigurationSourceSection)ConfigurationManager.GetSection(SectionName);
}

/// <summary>
/// Gets or sets the name for the default configuration source.
/// </summary>
[ConfigurationProperty(selectedSourceProperty, IsRequired= true )]
public string SelectedSource
{
get
{
return ( string ) this [selectedSourceProperty];
}
set
{
this [selectedSourceProperty] = value ;
}
}

/// <summary>
/// Gets the collection of defined configuration sources.
/// </summary>
[ConfigurationProperty(sourcesProperty, IsRequired = true )]
public NameTypeConfigurationElementCollection<ConfigurationSourceElement, ConfigurationSourceElement> Sources
{
get
{
return (NameTypeConfigurationElementCollection<ConfigurationSourceElement, ConfigurationSourceElement>) this [sourcesProperty];
}

}
}

可以看出,這里實際上是從App.config或者Web.config中讀取節enterpriseLibrary.ConfigurationSource

這是Entlib4里面新加入的功能,可以把配置節獨立出來存儲到別的文件中,沒有嘗試過的朋友可以打開微軟企業庫4.1試一試

image

這樣的話,也就是說,如果選擇了ConfigurationSource的話就從該位置讀取配置,否則就從SystemConfigurationSource讀取配置

之后自然是順理成章的從dataConfiguration配置節中讀取DefaultDatabase,并且替換context中的BuildKey中的null值。

EntLib的龐大實在是令我崩潰,只好把這個策略再劃分出來了。

不過不得不佩服ObjectBuilder的設計者,太強大了。

微軟企業庫源碼解析——DAAB(二)DatabaseFactory(ConfigurationNameMappingStrategy篇)


更多文章、技術交流、商務合作、聯系博主

微信掃碼或搜索:z360901061

微信掃一掃加我為好友

QQ號聯系: 360901061

您的支持是博主寫作最大的動力,如果您喜歡我的文章,感覺我的文章對您有幫助,請用微信掃描下面二維碼支持博主2元、5元、10元、20元等您想捐的金額吧,狠狠點擊下面給點支持吧,站長非常感激您!手機微信長按不能支付解決辦法:請將微信支付二維碼保存到相冊,切換到微信,然后點擊微信右上角掃一掃功能,選擇支付二維碼完成支付。

【本文對您有幫助就好】

您的支持是博主寫作最大的動力,如果您喜歡我的文章,感覺我的文章對您有幫助,請用微信掃描上面二維碼支持博主2元、5元、10元、自定義金額等您想捐的金額吧,站長會非常 感謝您的哦!!!

發表我的評論
最新評論 總共0條評論
主站蜘蛛池模板: 久久午夜电影网 | 99av涩导航 | 奇米777视频 | 鲁丝片一区二区三区毛片 | 国产美女主播在线观看 | 99精品视频在线视频免费观看 | 午夜影院18| 亚洲精品中文字幕在线观看 | 日日操网站 | 成人免费视频网站在线观看 | 天堂国产| 国产做国产爱免费视频 | 欧美一区免费 | 四虎av电影| 久久五月婷 | xxxxxx免费| 玖玖精品视频在线观看 | 国产成人精品福利色多多 | 欧美精品片| 91精品国产综合久久精品 | 国产一区二区三区久久久久久久久 | 色综合久久88色综合天天 | 久久久女 | 九九热在线免费视频 | 特黄特色的免费大片看看 | 成人国产精品免费视频 | 国产网址在线观看 | 丁香花婷婷 | 久久久久亚洲精品 | 91在线短视频 | 天天干夜夜噜 | 国产成人免费高清激情视频 | 欧美二区视频 | 日韩视频在线播放 | 天天综合亚洲 | 777久久婷婷成人综合色 | 亚洲国产成人精品女人久久久 | 日本www.在线中文字幕 | 欧美中文字幕一区二区 | 污网站在线免费看 | 美女下面直流白浆视频 |