成人免费xxxxx在线视频软件_久久精品久久久_亚洲国产精品久久久_天天色天天色_亚洲人成一区_欧美一级欧美三级在线观看

想愛(ài)容易相處難:當(dāng)ASP.NET MVC愛(ài)上IoC

開(kāi)發(fā)
也許你會(huì)問(wèn)ASP.NET MVC為什么會(huì)愛(ài)上IoC?相愛(ài)的理由常常很簡(jiǎn)單,就像一首歌中所唱——“只為相遇那一個(gè)眼神”。而ASP.NET MVC愛(ài)上IoC只為IoC能實(shí)現(xiàn)MVC控制器的依賴注入。

也許你會(huì)問(wèn)ASP.NET MVC為什么會(huì)愛(ài)上IoC?

相愛(ài)的理由常常很簡(jiǎn)單,就像一首歌中所唱——“只為相遇那一個(gè)眼神”。

而ASP.NET MVC愛(ài)上IoC只為IoC能實(shí)現(xiàn)MVC控制器的依賴注入。

下面是一個(gè)網(wǎng)站所用的一個(gè)MVC控制器:

  1. public class EnterpriseController  
  2. {  
  3.     protected IJobService _jobService;  
  4.     protected IEnterpriseService _enterpriseService;  
  5.  
  6.     #region Constructors  
  7.     public EnterpriseController(IJobService jobService,   
  8.         IEnterpriseService enterpriseService)  
  9.     {  
  10.         _jobService = jobService;  
  11.         _enterpriseService = enterpriseService;  
  12.     }  
  13.     #endregion  

如上面的代碼所示,有了IoC進(jìn)行依賴注入,就不需要在構(gòu)造函數(shù)中專門(mén)創(chuàng)建對(duì)應(yīng)于_jobService與_enterpriseService的實(shí)例。IoC容器會(huì)在運(yùn)行時(shí)自動(dòng)創(chuàng)建IJobService與IEnterpriseService的實(shí)例,并傳遞給EnterpriseController的構(gòu)造函數(shù)。

就因?yàn)檫@一點(diǎn),MVC就愛(ài)上了IoC。愛(ài)就這么簡(jiǎn)單。

但是相愛(ài)容易,相處難。。。相處的過(guò)程中總會(huì)遇到各種各樣的問(wèn)題。。。所以幸福來(lái)自于你是否能努力解決這些問(wèn)題。

代碼世界也一樣,當(dāng)我們讓MVC與IoC相處時(shí),就遇到了問(wèn)題。這里我們以IoC容器Unity為例,說(shuō)明一下我們遇到的問(wèn)題與解決方法。

要想實(shí)現(xiàn)Controller的依賴注入,就需要讓IoC容器接管Controller的創(chuàng)建,而ASP.NET MVC 3中提供的IDependencyResolver接口就為實(shí)現(xiàn)這個(gè)提供了可能。所以,我們首先創(chuàng)建一個(gè)實(shí)現(xiàn)IDependencyResolver接口的UnityDependencyResolver類(lèi),代碼如下:

  1. public class UnityDependencyResolver : IDependencyResolver  
  2. {  
  3.     IUnityContainer container;  
  4.  
  5.     public UnityDependencyResolver(IUnityContainer container)  
  6.     {  
  7.         this.container = container;  
  8.     }  
  9.  
  10.     public object GetService(Type serviceType)  
  11.     {  
  12.         return container.Resolve(serviceType);  
  13.     }  
  14.  
  15.     public IEnumerable<object> GetServices(Type serviceType)  
  16.     {  
  17.         return container.ResolveAll(serviceType);  
  18.     }  

UnityDependencyResolver的作用就是調(diào)用IoC容器(這里是Unity)解析相應(yīng)類(lèi)型的實(shí)例。創(chuàng)建了UnityDependencyResolver,我們還需要告訴MVC用它進(jìn)行解析。在Global.asax的Application_Start()方法中添加如下代碼:

  1. protected void Application_Start()  
  2. {  
  3.     IUnityContainer container = new UnityContainer();  
  4.     DependencyResolver.SetResolver(new UnityDependencyResolver(container));  

我們運(yùn)行一下程序試試,出現(xiàn)下面的錯(cuò)誤提示:

The current type, System.Web.Mvc.IControllerFactory, is an interface and cannot be constructed. Are you missing a type mapping?

從上面的錯(cuò)誤信息可以分析出,錯(cuò)誤是發(fā)生在調(diào)用UnityDependencyResolver.GetService方法時(shí)。ASP.NET MVC在運(yùn)行的時(shí)候需要得到IControllerFactory的實(shí)現(xiàn)實(shí)例,然后用它去創(chuàng)建相應(yīng)的控制器實(shí)例。如果不用IoC容器,MVC默認(rèn)會(huì)創(chuàng)建DefaultControllerFactory的實(shí)例。現(xiàn)在用了IoC,MVC找不到IControllerFactory的實(shí)現(xiàn)實(shí)例(我們根本沒(méi)有注冊(cè)嘛),所以出現(xiàn)上面的錯(cuò)誤。

為了解決這個(gè)問(wèn)題,我們注冊(cè)一下DefaultControllerFactory:

  1. container.RegisterType<IControllerFactory, DefaultControllerFactory>(); 

繼續(xù)運(yùn)行程序,又出現(xiàn)新的錯(cuò)誤:

The current type, System.Web.Mvc.IControllerActivator, is an interface and cannot be constructed. Are you missing a type mapping?

找不到IControllerActivator的實(shí)現(xiàn)實(shí)例,看來(lái),創(chuàng)建Controller還需要這個(gè)東東。查看MVC的源代碼發(fā)現(xiàn)IControllerActivator的默認(rèn)實(shí)現(xiàn)是DefaultControllerActivator,但郁悶的是它竟然是private class,無(wú)法注冊(cè)它。別無(wú)選擇,只能自己實(shí)現(xiàn)IControllerActivator,名叫CustomControllerActivator,代碼如下:

  1. public class CustomControllerActivator : IControllerActivator  
  2. {          
  3.     IController IControllerActivator.Create(  
  4.         System.Web.Routing.RequestContext requestContext,  
  5.         Type controllerType)  
  6.     {  
  7.         return DependencyResolver.Current  
  8.             .GetService(controllerType) as IController;  
  9.     }        

繼續(xù)運(yùn)行,又出現(xiàn)新的錯(cuò)誤:

The current type, System.Web.Mvc.IViewPageActivator, is an interface and cannot be constructed. Are you missing a type mapping?

天哪!難道MVC中的所有接口都要注冊(cè)一下。。。

這時(shí),腦子里突然閃出一個(gè)指示牌:

 

[[40973]]

 

于是,腳踩剎車(chē),打了一把方向盤(pán),駛上了另一條道 —— 如果IoC容器中沒(méi)有注冊(cè),不引發(fā)異常,而是返回null,讓MVC用自己的方式去處理。

修改UnityDependencyResolver的GetService方法:

  1. public object GetService(Type serviceType)  
  2. {  
  3.     if (!this.container.IsRegistered(serviceType))  
  4.     {  
  5.         return null;  
  6.     }  
  7.     return container.Resolve(serviceType);  

并取消之前在IoC容器中對(duì)DefaultControllerFactory與CustomControllerActivator的注冊(cè)。

繼續(xù)運(yùn)行,成功!雖然成功,但停車(chē)一看,原來(lái)兜了一個(gè)圈子,又回到了出發(fā)的地方。一切還是交由MVC處理,IoC容器形同虛設(shè),Controller的依賴注入無(wú)法實(shí)現(xiàn)。如果這時(shí)訪問(wèn)想依賴注入的Controller(構(gòu)造函數(shù)帶有參數(shù)),會(huì)出現(xiàn)下面的錯(cuò)誤提示:

  1. No parameterless constructor defined for this object. 

雖然回到原地,看上去沒(méi)有前進(jìn)一步,但實(shí)際上你已離目標(biāo)更近一些(積累了經(jīng)驗(yàn),下次前進(jìn)速度會(huì)更快)。就像你追一個(gè)女孩子,費(fèi)盡心思,卻被拒絕,看似你的一切努力付之流水,實(shí)際上她的心門(mén)已經(jīng)有點(diǎn)松動(dòng)。。。這時(shí),你要有一種鍥而不舍的精神,把失落感扔到九霄云外,然后繼續(xù)努力,堅(jiān)信“精誠(chéng)所至,金石為開(kāi)”。解決技術(shù)問(wèn)題也是同樣道理。

重頭再來(lái)!閱讀MVC的源代碼,了解MVC的請(qǐng)求處理過(guò)程,看看MVC是在什么地方創(chuàng)建Controller的實(shí)例的,然后看有沒(méi)有辦法讓IoC容器來(lái)接管。

MvcHandler.BeginProcessRequest->MvcHandler.ProcessRequestInit,呵呵,找到:

  1. factory = ControllerBuilder.GetControllerFactory();  
  2. controller = factory.CreateController(RequestContext, controllerName); 

上面的代碼中,factory的類(lèi)型是IControllerFactory,ControllerBuilder.GetControllerFactory()的作用是獲取IControllerFactory的實(shí)現(xiàn)實(shí)例,而實(shí)際是通過(guò)調(diào)用IDependencyResolver接口得到的(我們之前實(shí)現(xiàn)的UnityDependencyResolver接管了IDependencyResolver接口)。但我們沒(méi)有在IoC容器中注冊(cè)IControllerFactory,實(shí)際是由MVC返回IControllerFactory的默認(rèn)實(shí)現(xiàn)DefaultControllerFactory。從上面的代碼還可以看出,Controller實(shí)例的創(chuàng)建是通過(guò)調(diào)用IControllerFactory.CreateController()方法,所以,我們要在DefaultControllerFactory.CreateController()方法中尋找線索,對(duì)應(yīng)代碼如下:

  1. public virtual IController CreateController(RequestContext requestContext, string controllerName) {  
  2.     Type controllerType = GetControllerType(requestContext, controllerName);  
  3.     IController controller = GetControllerInstance(requestContext, controllerType);  
  4.     return controller;  

CreateController()又調(diào)用了GetControllerInstance()得到Controller的實(shí)例,進(jìn)一步查看其代碼:

  1. protected internal virtual IController GetControllerInstance(RequestContext requestContext, Type controllerType) {  
  2.     return ControllerActivator.Create(requestContext, controllerType);  

ControllerActivator的類(lèi)型是IControllerActivator,之前也提到過(guò),IControllerActivator的默認(rèn)實(shí)現(xiàn)是DefaultControllerActivator,由此可以看出,Controller實(shí)例的創(chuàng)建是由DefaultControllerActivator完成的。我們要實(shí)現(xiàn)依賴注入,就要由IoC容器來(lái)接管。

那如何來(lái)接管呢?——重載DefaultControllerFactory的CreateController方法,將創(chuàng)建Controller實(shí)例的工作轉(zhuǎn)交給IoC容器,代碼如下:

  1. public class UnityControllerFactory : DefaultControllerFactory  
  2. {  
  3.     IUnityContainer container;  
  4.     public UnityControllerFactory(IUnityContainer container)  
  5.     {  
  6.         this.container = container;  
  7.     }  
  8.  
  9.     protected override IController GetControllerInstance(RequestContext reqContext,  
  10.         Type controllerType)  
  11.     {  
  12.         return container.Resolve(controllerType) as IController;  
  13.     }  

然后在IoC容器中注冊(cè)一下UnityControllerFactory:

  1. container.RegisterType<IControllerFactory, UnityControllerFactory>(); 

然后,運(yùn)行程序。。。功夫不負(fù)有心人,依賴注入成功,問(wèn)題解決!從此,MVC與IoC過(guò)上了幸福的生活。

 

[[40974]]

 

小結(jié)

要實(shí)現(xiàn)ASP.NET MVC控制器的依賴注入,我們需要:

1. 實(shí)現(xiàn)IDependencyResolver接口并通過(guò)DependencyResolver.SetResolver告知MVC,將部分類(lèi)型實(shí)例解析工作交由IoC容器來(lái)處理;

2. 繼承DefaultControllerFactory,重載GetControllerInstance方法,并通過(guò)IoC容器將之注冊(cè)為IControllerFactory的實(shí)現(xiàn)。

完整示例代碼下載

原文:http://www.cnblogs.com/dudu/archive/2011/08/15/mvc_ioc_dependency_injection.html

責(zé)任編輯:陳貽新 來(lái)源: dudu的博客
相關(guān)推薦

2014-07-29 10:00:30

ASP.NETMVCAutoFac

2009-07-24 13:20:44

MVC框架ASP.NET

2009-07-31 12:43:59

ASP.NET MVC

2012-12-24 10:00:07

ASP.NETjQueryAjax

2009-07-22 13:24:24

ASP.NET MVC

2009-07-22 10:09:59

ASP.NET MVC

2009-07-23 14:31:20

ASP.NET MVC

2009-07-23 15:44:39

ASP.NET MVC

2009-07-20 10:53:59

ASP.NET MVC

2010-06-23 15:44:03

ASP.NET MVC

2010-03-19 09:17:16

ASP.NET MVC

2009-07-24 11:33:12

MVC單元測(cè)試ASP.NET

2009-07-22 10:34:37

ActionInvokASP.NET MVC

2009-07-22 13:08:55

拯救UpdatePanASP.NET MVC

2009-07-20 15:44:32

ASP.NET MVC

2009-07-22 10:13:31

異步ActionASP.NET MVC

2009-07-23 11:33:18

2009-07-29 09:17:12

jQuery刪除

2009-07-22 09:11:02

Action方法ASP.NET MVC

2009-04-01 12:00:43

ASP.NETMVC
點(diǎn)贊
收藏

51CTO技術(shù)棧公眾號(hào)

主站蜘蛛池模板: 国产精品视频免费播放 | 色吧色综合 | 91av视频在线 | 国产精品久久久久久久久久久久久 | 免费一看一级毛片 | www.47久久青青 | 日韩欧美在线视频 | 国产精品久久久久久久久污网站 | 色爱区综合 | 一区二区欧美在线 | 99re在线视频 | 男人的天堂久久 | 久久av一区二区 | 91精品国产一区二区三区 | 亚洲精品1区 | 一区二区手机在线 | 欧美电影免费观看 | 亚洲欧美日韩中文字幕一区二区三区 | 精品粉嫩aⅴ一区二区三区四区 | 真人毛片| 日韩精品久久久久 | 久久精品视频在线观看 | 亚洲精品久久久久中文字幕欢迎你 | 99热最新网址 | 国产精品久久久久久久久久久新郎 | 暖暖成人免费视频 | 亚洲五码久久 | 91视视频在线观看入口直接观看 | 欧美一区二区三区的 | 91精品国产91久久久久福利 | 中文字幕日韩欧美一区二区三区 | 涩涩导航 | 午夜性色a√在线视频观看9 | 久久久久久久夜 | av在线播放网站 | 国产伦精品一区二区三毛 | 亚洲天堂av在线 | 国产欧美一区二区三区日本久久久 | 国产日韩欧美中文 | 91精品国产综合久久福利软件 | 无码一区二区三区视频 |