<output id="qn6qe"></output>

    1. <output id="qn6qe"><tt id="qn6qe"></tt></output>
    2. <strike id="qn6qe"></strike>

      亚洲 日本 欧洲 欧美 视频,日韩中文字幕有码av,一本一道av中文字幕无码,国产线播放免费人成视频播放,人妻少妇偷人无码视频,日夜啪啪一区二区三区,国产尤物精品自在拍视频首页,久热这里只有精品12

      代碼級淺析企業庫對象創建

             本來是沒有打算寫這篇分析的,但是在我分析緩存組件的時候,發現企業庫的所有組件都是通過一種方式創建出來的,這就讓我產生了好奇,于是決定去看看他到底是如何通過配置文件將正確的對象創建出來.

       

       

            這里有四個重要的接口,一句話概括,就是配置器(IContainerConfigurator)以特定的解析方式(ITypeRegistrationsProvider)將源(IConfigurationSource)里的信息解析出來,最終發布為服務定位器(IServiceLocator).

       

            一.服務定位器

       

            可以從圖上看到,其實所謂的企業庫服務定位器,其實就是對依賴注入框架Unity的一個封裝,通過GetInstance<T>方法來解析接口及其實現類的匹配.

       

            二.配置器

       

            配置器是一個完成類型注冊的過程.從圖上可以看到,Unity容器內的注冊信息是通過UnityContainerConfigurator來進行注冊的.進行注冊的代碼為:

       

      container.RegisterType(registrationEntry.ServiceType, registrationEntry.ImplementationType, registrationEntry.Name, CreateLifetimeManager(registrationEntry), GetInjectionMembers(registrationEntry));

       

            其本質是向Unity容器進行類型注冊.注冊完成之后,就可以通過UnityServiceLocator向外提供服務了.

       

            三.配置源


            我們的配置信息一般寫在系統的配置文件中,而IconfigurationSource接口則負責從文件中讀取相關信息.從上圖可以看到,真正的實現類是SystemConfigurationSource類. 在其里面有這樣一句代碼:

      return AppDomain.CurrentDomain.SetupInformation.ConfigurationFile;

            這也決定了系統只能從默認的配置文件中讀取信息.

       

            四.解析方式

       

            可以從圖中看到,所以解析,就是把配置文件分析成一個接口與實現類的映射表.TypeRegistrationProvidersConfigurationSection,TypeRegistrationProviderElementCollection與TypeRegistrationProviderElement,分別對應配置文件里的配置節,配置元素集合與配置元素,BlockSectionNames類則定義了企業庫使用的配置節名稱.重點看ConfigurationBasedTypeRegistrationsProviderFactory類的CreateTypeRegistrationsProviderLocators方法,代碼如下:

       

       1 TypeRegistrationProvidersConfigurationSection section = configurationSource.GetSection(TypeRegistrationProvidersConfigurationSection.SectionName) as TypeRegistrationProvidersConfigurationSection;
       2 if (section == null)
       3 {
       4     section = new TypeRegistrationProvidersConfigurationSection();
       5 }
       6 
       7 foreach (TypeRegistrationProviderElement typeRegistrationProviderElement in section.TypeRegistrationProviders)
       8 {
       9     if (!string.IsNullOrEmpty(typeRegistrationProviderElement.SectionName) &&
      10         !string.IsNullOrEmpty(typeRegistrationProviderElement.ProviderTypeName))
      11     {
      12         throw new ConfigurationErrorsException(
      13             string.Format("Type Registration Provider Settings '{0}' cannot declare both sectionName and providerType attributes",
      14             typeRegistrationProviderElement.Name));
      15     }
      16     if (!string.IsNullOrEmpty(typeRegistrationProviderElement.SectionName))
      17     {
      18         yield return new ConfigSectionLocator(typeRegistrationProviderElement.SectionName, reconfiguringEventSource);
      19     }
      20     else if (!string.IsNullOrEmpty(typeRegistrationProviderElement.ProviderTypeName))
      21     {
      22         yield return new TypeLoadingLocator(typeRegistrationProviderElement.ProviderTypeName, reconfiguringEventSource);
      23     }
      24 }

            第四行新建了一個TypeRegistrationProvidersConfigurationSection對象,其TypeRegistrationProviders屬性在返回時,會創建庫業庫默認使用的節點集合,代碼如下:

      public TypeRegistrationProviderElementCollection()
      {
          BaseAdd(new TypeRegistrationProviderElement() { Name = TypeRegistrationProvidersConfigurationSection.CachingTypeRegistrationProviderName, SectionName = BlockSectionNames.Caching });
          BaseAdd(new TypeRegistrationProviderElement() { Name = TypeRegistrationProvidersConfigurationSection.CryptographyTypeRegistrationProviderName, SectionName = BlockSectionNames.Cryptography });
          BaseAdd(new TypeRegistrationProviderElement() { Name = TypeRegistrationProvidersConfigurationSection.ExceptionHandlingTypeRegistrationProviderName, SectionName = BlockSectionNames.ExceptionHandling });
          BaseAdd(new TypeRegistrationProviderElement() { Name = TypeRegistrationProvidersConfigurationSection.InstrumentationTypeRegistrationProviderName, SectionName = BlockSectionNames.Instrumentation });
          BaseAdd(new TypeRegistrationProviderElement() { Name = TypeRegistrationProvidersConfigurationSection.LoggingTypeRegistrationProviderName, SectionName = BlockSectionNames.Logging });
          BaseAdd(new TypeRegistrationProviderElement() { Name = TypeRegistrationProvidersConfigurationSection.PolicyInjectionTypeRegistrationProviderName, SectionName = BlockSectionNames.PolicyInjection });
          BaseAdd(new TypeRegistrationProviderElement() { Name = TypeRegistrationProvidersConfigurationSection.SecurityTypeRegistrationProviderName, SectionName = BlockSectionNames.Security });
          BaseAdd(new TypeRegistrationProviderElement() { Name = TypeRegistrationProvidersConfigurationSection.DataAccessTypeRegistrationProviderName, ProviderTypeName = BlockSectionNames.DataRegistrationProviderLocatorType });
          BaseAdd(new TypeRegistrationProviderElement() { Name = TypeRegistrationProvidersConfigurationSection.ValidationTypeRegistrationProviderName,  ProviderTypeName = BlockSectionNames.ValidationRegistrationProviderLocatorType });
      }

       

            下面就是讀取這些節點的信息了, 代碼第18行與第22行就是跟據不同的情況創建不同的定位器.

            到目前為止, 只是知道了企業庫會使用哪些配置節,那具體的分析工作呢,還是回到UnityContainerConfigurator類吧:

       1 protected override void RegisterAllCore(IConfigurationSource configurationSource, ITypeRegistrationsProvider rootProvider)
       2 {
       3     EnterWriteLock();
       4     try
       5     {
       6         foreach (var registration in rootProvider.GetRegistrations(configurationSource))
       7         {
       8             Register(registration);
       9         }
      10     }
      11     finally
      12     {
      13         ExitWriteLock();
      14     }
      15 }

            可以看到由ITypeRegistrationsProvider接口完成.而TypeRegistrationsProvider抽象類實現了這個接口,TypeLoadingLocator與ConfigSectionLocator又繼承了這個抽象類.隨便看一個吧:

      public override IEnumerable<TypeRegistration> GetRegistrations(IConfigurationSource configurationSource)
      {
          return GetRegistrationsInternal(configurationSource, (p, cs) => p.GetRegistrations(cs));
      }

       

       1 private IEnumerable<TypeRegistration> GetRegistrationsInternal(IConfigurationSource configurationSource,
       2     Func<ITypeRegistrationsProvider, IConfigurationSource, IEnumerable<TypeRegistration>> registrationsAccessor)
       3 {
       4     ITypeRegistrationsProvider provider = null;
       5     ConfigurationSection section = configurationSource.GetSection(Name);
       6     if (section != null)
       7     {
       8         provider = section as ITypeRegistrationsProvider;
       9     }
      10 
      11     if (provider != null)
      12     {
      13         return registrationsAccessor(provider, configurationSource);
      14     }
      15     return Enumerable.Empty<TypeRegistration>();
      16 }

            其首先從源中獲取指定節點,然后把其強轉成ITypeRegistrationsProvider再調用其GetRegistrations方法獲取真正的配置信息.比如緩存配置,用GetSection獲取后其實就是CacheManagerSettings類,其實現了ITypeRegistrationsProvider接口,調用其GetRegistrations方法解析緩存配置.


            是不是感覺很亂?反正我是這么認為的.搞不懂不就是解析一個配置文件嘛,干嘛要搞這么復雜,難道不多轉幾個彎就不能體現企業庫的NB與價值?!個人感覺最亂的就是對于ITypeRegistrationsProvider接口的使用.UnityContainerConfigurator類調用ITypeRegistrationsProvider接口,實際是調用CompositeTypeRegistrationsProviderLocator類.這個類的內部維護了一個ITypeRegistrationsProvider接口集合,其GetRegistrations方法就是遍例這個集合逐個調用各自GetRegistrations方法.實際上這個集合裝著的是TypeLoadingLocator類與ConfigSectionLocator類,那么調用的就是這兩個類的方法.然后這兩個類又把源獲取一遍,把獲取的結果轉成ITypeRegistrationsProvider接口,然后再調轉換后的GetRegistrations方法.到了這一步,才真正把該拿的信息拿出來!有必要搞的這么復雜嗎?!

       

            參考的文章:

            微軟企業庫5.0學習筆記

       

      posted @ 2011-12-18 18:31  永遠的阿哲  閱讀(456)  評論(0)    收藏  舉報
      主站蜘蛛池模板: 国产午夜福利一区二区三区| 亚洲区激情区无码区日韩区| 亚洲精品无码久久一线| 欧美乱码精品一区二区三区| 亚洲AV无码秘?蜜桃蘑菇| 亚洲一区二区中文av| 会宁县| 久久久久青草线蕉综合超碰| 亚洲国产精品自产在线播放| 精品人妻伦一二二区久久| 亚洲国产成人精品无色码| 亚洲精品日韩在线观看| 国内少妇人妻偷人精品视频| 久久www免费人成看片中文| 木兰县| 北辰区| 亚洲成aⅴ人在线电影| 亚洲第一视频区| 国内极度色诱视频网站| 国产成人午夜福利精品| 性欧美vr高清极品| 亚洲中文字幕人成影院| 永久免费在线观看蜜桃视频| 亚洲中文字幕乱码一区| 四虎永久免费高清视频| h无码精品3d动漫在线观看| 一本高清码二区三区不卡| 久久青青草原亚洲AV无码麻豆| 亚洲五月天一区二区三区| 五级黄高潮片90分钟视频 | 久久精品免视看国产成人| 国产l精品国产亚洲区 | av中文字幕在线二区| 亚洲一区在线成人av| 无码熟妇人妻av影音先锋| 久九九精品免费视频| 国产片av在线观看国语| 无码国产精品一区二区VR老人| 成人免费在线播放av| 亚洲AV国产福利精品在现观看| 久久夜色撩人国产综合av |