這篇文章主要講解了“ASP.NET MVC示例項(xiàng)目分析”,文中的講解內(nèi)容簡(jiǎn)單清晰,易于學(xué)習(xí)與理解,下面請(qǐng)大家跟著小編的思路慢慢深入,一起來研究和學(xué)習(xí)“ASP.NET MVC示例項(xiàng)目分析”吧!
目前創(chuàng)新互聯(lián)已為上1000家的企業(yè)提供了網(wǎng)站建設(shè)、域名、網(wǎng)絡(luò)空間、網(wǎng)站托管運(yùn)營(yíng)、企業(yè)網(wǎng)站設(shè)計(jì)、繁峙網(wǎng)站維護(hù)等服務(wù),公司將堅(jiān)持客戶導(dǎo)向、應(yīng)用為本的策略,正道將秉承"和諧、參與、激情"的文化,與客戶和合作伙伴齊心協(xié)力一起成長(zhǎng),共同發(fā)展。
在這個(gè)ASP.NET MVC 示例:Suteki.Shop中,未使用微軟自已的Unity框架來實(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):也就是我們通常所說的業(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ù)接口來使用。
還記得上一篇文章中提到的Service嗎? 說白了,它就是一個(gè)服務(wù)。而Suteki.Shop做的更“夸張”,要是帶有業(yè)務(wù)邏輯性質(zhì)的功能代碼都可以被視為Component或服務(wù),比如說前幾篇文章中所提到的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)的,下面是該方法的聲明:
ASP.NET MVC 示例代碼
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)上有不少,園子里也有不少朋友寫過,這里就不做說明了。
接就上面方法就會(huì)運(yùn)行InitializeWindsor(),這就是Windsor容器初始化的方法:
ASP.NET MVC 示例代碼
/// < 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方法來從外部的config文件中加載默認(rèn)信息。我們這里就看一下Build方法的實(shí)現(xiàn):
ASP.NET MVC 示例代碼:
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被指定為Transient類型,這里有必要介紹一下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)目中,組件的生命周期基本上都被指定成為Transient類型,即當(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)類,其這種硬編碼的方法是是一種“可選”方式。
說完了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 ); } }
如前面所說的,擴(kuò)張單元插件(Facilities)可以在不更改原有組件的基礎(chǔ)上注入你所需要的功能代碼,這里就使用了其AddFacility方法來添加擴(kuò)展單元來注冊(cè)并管理我們的Windows Live Writer組件。
下面繼分析InitializeWindsor方法中的其余代碼,看完了ConfigureContainer方法,接著就是下面這一行代碼了:
ServiceLocator.SetLocatorProvider(() => container.Resolve< IServiceLocator>());
剛看到這一行讓我感覺似曾相識(shí),記得以前在看Oxite的Global.asax中也看過類似的這樣一行代碼。
ServiceLocator.SetLocatorProvider(() => new UnityServiceLocator(container));
只不過那個(gè)項(xiàng)目中用的是 Unity而不是Castle Windsor。但實(shí)際的功能是一樣的。即完成對(duì)容器中服務(wù)地址的解析綁定。有了它,就可以通過Microsoft.Practices.ServiceLocation.ServiceLocatorImplBase中所定義的方法如:DoGetInstance或DoGetAllInstances 來獲取相應(yīng)的服務(wù)組件(集合)的實(shí)例。
比如本項(xiàng)目中的DoGetInstance及DoGetAllInstances()實(shí)現(xiàn)代碼如下:
(ASP.NET MVC 示例代碼: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));
這里要說明的是WindsorControllerFactory這個(gè)類是在 MvcContrib項(xiàng)目中提供的,用于構(gòu)造一個(gè)Castle項(xiàng)目類型的Controller工廠。
感謝各位的閱讀,以上就是“ASP.NET MVC示例項(xiàng)目分析”的內(nèi)容了,經(jīng)過本文的學(xué)習(xí)后,相信大家對(duì)ASP.NET MVC示例項(xiàng)目分析這一問題有了更深刻的體會(huì),具體使用情況還需要大家實(shí)踐驗(yàn)證。這里是創(chuàng)新互聯(lián),小編將為大家推送更多相關(guān)知識(shí)點(diǎn)的文章,歡迎關(guān)注!
當(dāng)前題目:ASP.NETMVC示例項(xiàng)目分析
標(biāo)題URL:http://chinadenli.net/article12/jggodc.html
成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供微信公眾號(hào)、企業(yè)建站、全網(wǎng)營(yíng)銷推廣、網(wǎng)站內(nèi)鏈、網(wǎng)站制作、用戶體驗(yàn)
聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請(qǐng)盡快告知,我們將會(huì)在第一時(shí)間刪除。文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如需處理請(qǐng)聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時(shí)需注明來源: 創(chuàng)新互聯(lián)