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

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

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

      Asp.net MVC 示例項(xiàng)目"Suteki.Shop"分析之---IOC(控制反轉(zhuǎn))

            在Suteki.Shop中,未使用微軟自已的Unity框架來(lái)實(shí)現(xiàn)IOC,而是使用了大名鼎鼎Castle Windsor。
      因?yàn)橐昧薟indsor,就有必要簡(jiǎn)要介紹一下。而我的理解,這個(gè)IOC容器(Container)包括下面幾個(gè)
      重要概念:
       

            容器(Container):Windsor是一個(gè)反轉(zhuǎn)控制容器。它創(chuàng)建在一個(gè)微內(nèi)核的基礎(chǔ)之上,這個(gè)微內(nèi)
      核能夠掃描類并且試圖找到這些類用到哪些對(duì)象引用、對(duì)象依賴,然后把這些依賴信息提供給類使用

            組件(Component):也就是我們通常所說(shuō)的業(yè)務(wù)邏輯單元及相應(yīng)的功能實(shí)現(xiàn),組件是一個(gè)可復(fù)
      用的代碼單元。它應(yīng)該實(shí)現(xiàn)并暴露為一個(gè)服務(wù)。組件是實(shí)現(xiàn)一個(gè)服務(wù)或接口的類

            服務(wù)(Service) :也就是相應(yīng)的組件接口或N個(gè)Component按業(yè)務(wù)邏輯組合而成的業(yè)務(wù)邏輯接口。
      接口是服務(wù)的規(guī)范,它創(chuàng)建一個(gè)抽象層,你可以輕松的替換服務(wù)的實(shí)現(xiàn)

            擴(kuò)張單元插件(Facilities):提供(可擴(kuò)張)容器以管理組件
            
           我們可以直接使用組件(會(huì)在下面的內(nèi)容中提到),也可以把組件轉(zhuǎn)換成相應(yīng)的服務(wù)接口來(lái)使用。
       
           還記得上一篇文章中提到的Service嗎? 說(shuō)白了,它就是一個(gè)服務(wù)。而Suteki.Shop做的更“夸張”,
      只要是帶有業(yè)務(wù)邏輯性質(zhì)的功能代碼都可以被視為Component或服務(wù),比如說(shuō)前幾篇文章中所提到的
      Filter,ModelBinder。甚至是服務(wù)組件初始化的輔助類(WindsorServiceLocator)也一并拿下。


           為了便于理解,下面就到Suteki.Shop中看一下其是如何做的:)
         
           首先我們看一下整個(gè)Suteki.Shop項(xiàng)目啟動(dòng)的入口,同時(shí)這也是Windsor IOC容器初始化的起點(diǎn)。
      而這塊功能代碼是放在了Global.asax(Suteki.Shop\Global.asax)中的Application_Start方法中
      實(shí)現(xiàn)的,下面是該方法的聲明:

      protected void Application_Start(object sender, EventArgs e)
      {
          RouteManager.RegisterRoutes(RouteTable.Routes);
          InitializeWindsor();
      }

       

           代碼中的RouteManager.RegisterRoutes是實(shí)現(xiàn)對(duì)Route規(guī)則的綁定,而規(guī)則的內(nèi)容是被硬編碼到
      RouteManager中實(shí)現(xiàn)的。關(guān)于Route的資料網(wǎng)上有不少,園子里也有不少朋友寫(xiě)過(guò),這里就不做說(shuō)明了。

           接就上面方法就會(huì)運(yùn)行InitializeWindsor(),這就是Windsor容器初始化的方法:

      /// <summary>
      /// This web application uses the Castle Project's IoC container, Windsor see:
      /// http://www.castleproject.org/container/index.html
      /// </summary>
      protected virtual void InitializeWindsor()
      {
          
      if (container == null)
          {
              
      // create a new Windsor Container
              container = ContainerBuilder.Build("Configuration\\Windsor.config"); 

              WcfConfiguration.ConfigureContainer(container);

              ServiceLocator.SetLocatorProvider(() 
      => container.Resolve<IServiceLocator>());
              
      // set the controller factory to the Windsor controller factory (in MVC Contrib)
              System.Web.Mvc.ControllerBuilder.Current.SetControllerFactory(new WindsorControllerFactory(container));
          }
      }

       

            注:“Configuration\\Windsor.config”中的內(nèi)容較長(zhǎng),主要是一些XML配置節(jié)點(diǎn)。大家可以抽時(shí)
      間閱讀一下即可。

           這個(gè)方法是今天講解的主要內(nèi)容,下面就介紹一下其中的代碼。
         
           首先是判斷container(IWindsorContainer類型)是否為空,如果容器為空則創(chuàng)建并初始化該容器。
      也就是調(diào)用ContainerBuilder(Suteki.Shop\ContainerBuilder)類的Build方法來(lái)從外部的config文件
      中加載默認(rèn)信息。我們這里就看一下Build方法的實(shí)現(xiàn):

      public static IWindsorContainer Build(string configPath)
      {
              var container 
      = new WindsorContainer(new XmlInterpreter(configPath));

              
      // register handler selectors
              container.Kernel.AddHandlerSelector(new UrlBasedComponentSelector(
                  
      typeof(IBaseControllerService),
                  
      typeof(IImageFileService),
                  
      typeof(IConnectionStringProvider)
                  ));

              
      // automatically register controllers
              container.Register(AllTypes
                  .Of
      <Controller>()
                  .FromAssembly(Assembly.GetExecutingAssembly())
                  .Configure(c 
      => c.LifeStyle.Transient.Named(c.Implementation.Name.ToLower())));

              container.Register(
                  Component.For
      <IUnitOfWorkManager>().ImplementedBy<LinqToSqlUnitOfWorkManager>().LifeStyle.Transient,
                  Component.For
      <IFormsAuthentication>().ImplementedBy<FormsAuthenticationWrapper>(),
                  Component.For
      <IServiceLocator>().Instance(new WindsorServiceLocator(container)),
                  Component.For
      <AuthenticateFilter>().LifeStyle.Transient,
                  Component.For
      <UnitOfWorkFilter>().LifeStyle.Transient,
                  Component.For
      <DataBinder>().LifeStyle.Transient,
                  Component.For
      <LoadUsingFilter>().LifeStyle.Transient,
                  Component.For
      <CurrentBasketBinder>().LifeStyle.Transient,
                  Component.For
      <ProductBinder>().LifeStyle.Transient,
                  Component.For
      <OrderBinder>().LifeStyle.Transient,
                  Component.For
      <IOrderSearchService>().ImplementedBy<OrderSearchService>().LifeStyle.Transient,
                  Component.For
      <IEmailBuilder>().ImplementedBy<EmailBuilder>().LifeStyle.Singleton
              );

              
      return container;
      }

           

            首先是讀入指定配置文件的XML結(jié)點(diǎn)信息,將構(gòu)造一個(gè) WindsorContainer實(shí)現(xiàn),同時(shí)在其微內(nèi)核中
      添加“容器處理組件”的方式(AddHandlerSelector),注意這種處理方式是按我們?cè)跇I(yè)務(wù)邏輯中規(guī)定
      的方式處理的。

            緊跟著又向該容器中注冊(cè)了Controller,而且配置屬性的LifeStyle被指定為T(mén)ransient類型,這里
      有必要介紹一下Castle容器的組件生存周期,主要有如下幾種:   

          Singleton : 容器中只有一個(gè)實(shí)例將被創(chuàng)建
          Transient : 每次請(qǐng)求創(chuàng)建一個(gè)新實(shí)例
          PerThread: 每線程中只存在一個(gè)實(shí)例
          PerWebRequest : 每次web請(qǐng)求創(chuàng)建一個(gè)新實(shí)例
          Pooled :使用"池化"方式管理組件,可使用PooledWithSize方法設(shè)置池的相關(guān)屬性。

           

            可以看到在本項(xiàng)目中,組件的生命周期基本上都被指定成為T(mén)ransient類型,即當(dāng)請(qǐng)求發(fā)生時(shí)創(chuàng)建,
      在處理結(jié)束后銷毀。

            接著再看一下該方法的其余代碼,也就是對(duì)ModelBinder,F(xiàn)ilter,Service這類業(yè)務(wù)邏輯的組件注
      冊(cè)。同時(shí)我們看到有的組類在進(jìn)行接口注冊(cè)的同時(shí)還被綁定了默認(rèn)的實(shí)現(xiàn)類,其這種硬編碼的方法是
      是一種“可選”方式。


            說(shuō)完了Build方法之前,再回到Global.asax文件中的InitializeWindsor方法,看一下其余的代碼。
      我們看到這樣一行:
       

           WcfConfiguration.ConfigureContainer(container);

          
            類WcfConfiguration的ConfigureContainer方法就是繼續(xù)向當(dāng)前創(chuàng)建的容器中添加組件,而這次要
      加入的組件是Windows Live Writer的IMetaWeblog接口實(shí)現(xiàn)類,如下:

      public static class WcfConfiguration
      {
          
      public static void ConfigureContainer(IWindsorContainer container)
          {
              var returnFaults 
      = new ServiceDebugBehavior { IncludeExceptionDetailInFaults = true };

              container.AddFacility
      <WcfFacility>(f =>
              {
                  f.Services.AspNetCompatibility 
      = AspNetCompatibilityRequirementsMode.Required;
                  f.DefaultBinding 
      = new XmlRpcHttpBinding();
              })
                  .Register(
                      Component.For
      <IServiceBehavior>().Instance(returnFaults),
                      Component.For
      <XmlRpcEndpointBehavior>(),
                      Component.For
      <IMetaWeblog>().ImplementedBy<MetaWeblogWcf>().Named("metaWebLog").LifeStyle.Transient
                      );

          }
      }

       
            如前面所說(shuō)的,擴(kuò)張單元插件(Facilities)可以在不更改原有組件的基礎(chǔ)上注入你所需要的功能代碼,
      這里就使用了其AddFacility方法來(lái)添加擴(kuò)展單元來(lái)注冊(cè)并管理我們的Windows Live Writer組件。

            下面繼分析InitializeWindsor方法中的其余代碼,看完了ConfigureContainer方法,接著就是下面這
      一行代碼了:

           ServiceLocator.SetLocatorProvider(() => container.Resolve<IServiceLocator>());


        
            剛看到這一行讓我感覺(jué)似曾相識(shí),記得以前在看Oxite的Global.asax中也看過(guò)類似的這樣一行代碼。

           ServiceLocator.SetLocatorProvider(() => new UnityServiceLocator(container));  

           
            只不過(guò)那個(gè)項(xiàng)目中用的是 Unity而不是Castle Windsor。但實(shí)際的功能是一樣的。即完成對(duì)容器中服務(wù)
      地址的解析綁定。有了它,就可以通過(guò)Microsoft.Practices.ServiceLocation.ServiceLocatorImplBase
      中所定義的方法如:DoGetInstanceDoGetAllInstances 來(lái)獲取相應(yīng)的服務(wù)組件(集合)的實(shí)例。

           比如本項(xiàng)目中的DoGetInstance及DoGetAllInstances()實(shí)現(xiàn)代碼如下:

          (文件位于:Suteki.Common\Windsor\WindsorServiceLocator.cs):

      protected override object DoGetInstance(Type serviceType, string key)
      {
          
      if (key != null)
              
      return container.Resolve(key, serviceType);
          
      return container.Resolve(serviceType);
      }

      /// <summary>
      /// When implemented by inheriting classes, this method will do the actual work of
      /// resolving all the requested service instances.
      /// </summary>
      /// <param name="serviceType">Type of service requested.</param>
      /// <returns>
      /// Sequence of service instance objects.
      /// </returns>
      protected override IEnumerable<object> DoGetAllInstances(Type serviceType)
      {
          
      return (object[])container.ResolveAll(serviceType);
      }

              
              
            注,對(duì)該WindsorServiceLocator類的IOC綁定在ContainerBuilder.Build中,如下:  

       
        container.Register(
             Component.For
      <IUnitOfWorkManager>().ImplementedBy<LinqToSqlUnitOfWorkManager>().LifeStyle.Transient,
             Component.For
      <IFormsAuthentication>().ImplementedBy<FormsAuthenticationWrapper>(),
             Component.For
      <IServiceLocator>().Instance(new WindsorServiceLocator(container)),
       

           
           
            而InitializeWindsor方法中的最后一行代碼如下:    

           System.Web.Mvc.ControllerBuilder.Current.SetControllerFactory(new WindsorControllerFactory(container));

           
            這里要說(shuō)明的是WindsorControllerFactory這個(gè)類是在 MvcContrib項(xiàng)目中提供的,用于構(gòu)造一個(gè)
      Castle項(xiàng)目類型的Controller工廠。
           
          
            好了,今天的內(nèi)容可能有點(diǎn)雜,主要就是Castle鬧的,因?yàn)槠渲杏幸恍└拍钜私庵蟛拍馨秧?xiàng)目中
      的代碼看懂。不過(guò)從整體上來(lái)看,Suteki.Shop的IOC機(jī)制實(shí)現(xiàn)的還是很清晰的,沒(méi)什么太難看的代碼。

            今天就先到這里了。
          
           
         
            原文鏈接: http://www.rzrgm.cn/daizhj/archive/2009/05/26/1456678.html

            作者: daizhj,代震軍,LaoD

            Tags: mvc,Suteki.Shop,Castle,IOC

            網(wǎng)址: http://daizhj.cnblogs.com/
        
         

      posted @ 2009-05-26 08:51  代震軍  閱讀(6337)  評(píng)論(7)    收藏  舉報(bào)
      主站蜘蛛池模板: 久久―日本道色综合久久| 一女被多男玩喷潮视频| 激情欧美日韩一区二区| 国产一卡2卡三卡4卡免费网站| 国产一区二区三区四区五区加勒比 | 亚洲av永久一区二区| 亚洲AV无码成人网站久久精品| 伊人久久大香线蕉AV网禁呦| 亚洲日产韩国一二三四区| 欧美国产精品啪啪| 伊人久久精品无码二区麻豆| 中文字幕精品无码一区二区| 久久无码av中文出轨人妻| 国产熟女av一区二区三区| 平遥县| 日韩在线视频线观看一区| 国产不卡一区二区四区| 亚洲精品天堂一区二区| 亚洲色成人网站www永久四虎| 欧洲精品久久久AV无码电影| 丰满少妇熟乱xxxxx视频| 被黑人伦流澡到高潮HNP动漫| 日韩av一区二区三区在线| 色偷偷亚洲女人天堂观看| 一区二区三区成人| 少妇被躁爽到高潮无码文| 色吊a中文字幕一二三区| 泗水县| 成人看的污污超级黄网站免费| 久久久久久综合网天天| 亚洲人成网站999久久久综合| 天啦噜国产精品亚洲精品| 国产性色的免费视频网站| 毛茸茸性xxxx毛茸茸毛茸茸| 日韩亚洲国产激情一区二区| 少妇人妻偷人免费观看| 野花社区www高清视频| 午夜精品福利亚洲国产| 国产精品无码久久久久AV| 久久天天躁狠狠躁夜夜躁| 老妇肥熟凸凹丰满刺激|