国产精品电影_久久视频免费_欧美日韩国产激情_成年人视频免费在线播放_日本久久亚洲电影_久久都是精品_66av99_九色精品美女在线_蜜臀a∨国产成人精品_冲田杏梨av在线_欧美精品在线一区二区三区_麻豆mv在线看

想愛容易相處難:當ASP.NET MVC愛上IoC

開發
也許你會問ASP.NET MVC為什么會愛上IoC?相愛的理由常常很簡單,就像一首歌中所唱——“只為相遇那一個眼神”。而ASP.NET MVC愛上IoC只為IoC能實現MVC控制器的依賴注入。

也許你會問ASP.NET MVC為什么會愛上IoC?

相愛的理由常常很簡單,就像一首歌中所唱——“只為相遇那一個眼神”。

而ASP.NET MVC愛上IoC只為IoC能實現MVC控制器的依賴注入。

下面是一個網站所用的一個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進行依賴注入,就不需要在構造函數中專門創建對應于_jobService與_enterpriseService的實例。IoC容器會在運行時自動創建IJobService與IEnterpriseService的實例,并傳遞給EnterpriseController的構造函數。

就因為這一點,MVC就愛上了IoC。愛就這么簡單。

但是相愛容易,相處難。。。相處的過程中總會遇到各種各樣的問題。。。所以幸福來自于你是否能努力解決這些問題。

代碼世界也一樣,當我們讓MVC與IoC相處時,就遇到了問題。這里我們以IoC容器Unity為例,說明一下我們遇到的問題與解決方法。

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

  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的作用就是調用IoC容器(這里是Unity)解析相應類型的實例。創建了UnityDependencyResolver,我們還需要告訴MVC用它進行解析。在Global.asax的Application_Start()方法中添加如下代碼:

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

我們運行一下程序試試,出現下面的錯誤提示:

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

從上面的錯誤信息可以分析出,錯誤是發生在調用UnityDependencyResolver.GetService方法時。ASP.NET MVC在運行的時候需要得到IControllerFactory的實現實例,然后用它去創建相應的控制器實例。如果不用IoC容器,MVC默認會創建DefaultControllerFactory的實例。現在用了IoC,MVC找不到IControllerFactory的實現實例(我們根本沒有注冊嘛),所以出現上面的錯誤。

為了解決這個問題,我們注冊一下DefaultControllerFactory:

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

繼續運行程序,又出現新的錯誤:

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

找不到IControllerActivator的實現實例,看來,創建Controller還需要這個東東。查看MVC的源代碼發現IControllerActivator的默認實現是DefaultControllerActivator,但郁悶的是它竟然是private class,無法注冊它。別無選擇,只能自己實現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.     }        

繼續運行,又出現新的錯誤:

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

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

這時,腦子里突然閃出一個指示牌:

 

[[40973]]

 

于是,腳踩剎車,打了一把方向盤,駛上了另一條道 —— 如果IoC容器中沒有注冊,不引發異常,而是返回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容器中對DefaultControllerFactory與CustomControllerActivator的注冊。

繼續運行,成功!雖然成功,但停車一看,原來兜了一個圈子,又回到了出發的地方。一切還是交由MVC處理,IoC容器形同虛設,Controller的依賴注入無法實現。如果這時訪問想依賴注入的Controller(構造函數帶有參數),會出現下面的錯誤提示:

  1. No parameterless constructor defined for this object. 

雖然回到原地,看上去沒有前進一步,但實際上你已離目標更近一些(積累了經驗,下次前進速度會更快)。就像你追一個女孩子,費盡心思,卻被拒絕,看似你的一切努力付之流水,實際上她的心門已經有點松動。。。這時,你要有一種鍥而不舍的精神,把失落感扔到九霄云外,然后繼續努力,堅信“精誠所至,金石為開”。解決技術問題也是同樣道理。

重頭再來!閱讀MVC的源代碼,了解MVC的請求處理過程,看看MVC是在什么地方創建Controller的實例的,然后看有沒有辦法讓IoC容器來接管。

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

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

上面的代碼中,factory的類型是IControllerFactory,ControllerBuilder.GetControllerFactory()的作用是獲取IControllerFactory的實現實例,而實際是通過調用IDependencyResolver接口得到的(我們之前實現的UnityDependencyResolver接管了IDependencyResolver接口)。但我們沒有在IoC容器中注冊IControllerFactory,實際是由MVC返回IControllerFactory的默認實現DefaultControllerFactory。從上面的代碼還可以看出,Controller實例的創建是通過調用IControllerFactory.CreateController()方法,所以,我們要在DefaultControllerFactory.CreateController()方法中尋找線索,對應代碼如下:

  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()又調用了GetControllerInstance()得到Controller的實例,進一步查看其代碼:

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

ControllerActivator的類型是IControllerActivator,之前也提到過,IControllerActivator的默認實現是DefaultControllerActivator,由此可以看出,Controller實例的創建是由DefaultControllerActivator完成的。我們要實現依賴注入,就要由IoC容器來接管。

那如何來接管呢?——重載DefaultControllerFactory的CreateController方法,將創建Controller實例的工作轉交給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容器中注冊一下UnityControllerFactory:

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

然后,運行程序。。。功夫不負有心人,依賴注入成功,問題解決!從此,MVC與IoC過上了幸福的生活。

 

[[40974]]

 

小結

要實現ASP.NET MVC控制器的依賴注入,我們需要:

1. 實現IDependencyResolver接口并通過DependencyResolver.SetResolver告知MVC,將部分類型實例解析工作交由IoC容器來處理;

2. 繼承DefaultControllerFactory,重載GetControllerInstance方法,并通過IoC容器將之注冊為IControllerFactory的實現。

完整示例代碼下載

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

責任編輯:陳貽新 來源: dudu的博客
相關推薦

2014-07-29 10:00:30

ASP.NETMVCAutoFac

2009-07-31 12:43:59

ASP.NET MVC

2009-07-24 13:20:44

MVC框架ASP.NET

2012-12-24 10:00:07

ASP.NETjQueryAjax

2009-07-20 10:53:59

ASP.NET MVC

2009-07-23 15:44:39

ASP.NET MVC

2009-07-23 14:31:20

ASP.NET MVC

2009-07-22 13:24:24

ASP.NET MVC

2009-07-22 10:09:59

ASP.NET MVC

2009-07-22 10:13:31

異步ActionASP.NET MVC

2009-04-01 12:00:43

ASP.NETMVC

2009-07-20 15:44:32

ASP.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

2010-06-23 15:44:03

ASP.NET MVC

2009-07-24 11:33:12

MVC單元測試ASP.NET

2009-07-22 13:08:55

拯救UpdatePanASP.NET MVC

2009-07-22 10:34:37

ActionInvokASP.NET MVC

2010-03-19 09:17:16

ASP.NET MVC
點贊
收藏

51CTO技術棧公眾號

欧美视频久久| 亚洲欧美一区二区三区久本道91| 51久久精品夜色国产麻豆| 菠萝蜜视频国产在线播放| 一区二区三区在线视频观看58| 波多野结衣乳巨码无在线| 国产日韩欧美三区| 国产精品福利观看| 欧美顶级毛片在线播放| 麻豆成人在线看| 97久久网站| 亚洲视频在线免费观看| 狠狠躁少妇一区二区三区| 337p亚洲精品色噜噜| a√资源在线| 精品1区2区3区| 天堂资源在线中文| 欧美一区二区三区的| 国产超级va在线视频| 欧美视频一区二区| 日本福利在线| 亚洲成人aaa| 国产不卡网站| 日韩视频免费在线| 欧美黄色一级| 欧美制服第一页| 日韩aaaa| 国产欧美韩日| 久久国产88| 欧美性受xxxx黑人猛交88| 国产尤物一区二区在线| 大荫蒂性生交片| 久久精品日韩一区二区三区| 中文字幕高清20页| 精品福利樱桃av导航| 国产中文在线视频| 日韩一区二区三区视频| 在线观看三级视频| 日韩欧美一区二区免费| 天天综合网久久| 91欧美一区二区| 五月综合网站| 久久蜜桃一区二区| 亚洲精品福利视频| 美女扒开大腿让男人桶| 天堂日韩电影| 久久久久国产精品免费免费搜索| 欧美成人黑人猛交| 91尤物视频在线观看| 国产精品区在线| 亚洲国产精品自拍| 99reav在线| 亚洲精品久久久久国产| 日韩黄色三级| 国产精品自在线| 樱空桃在线播放| 国产日韩欧美精品电影三级在线| 日韩欧美亚洲| 日韩精品在线一区二区| 欧美91在线|欧美| 日韩av黄色在线观看| 亚洲成人精品| 四虎4hu永久免费入口| 国产精品国模大尺度视频| porn视频在线观看| 亚洲欧美综合图区| jlzzjlzz亚洲女人| 伊人久久大香线蕉成人综合网| 久久影院电视剧免费观看| 美女欧美视频在线观看免费 | 欧美国产视频在线| 污网站在线观看视频| 亚洲激情在线视频| 成人综合一区| 欧美另类videos| 亚洲午夜免费视频| 成人爽a毛片免费啪啪| 国产精品久久久久影院日本| 精品无人区卡一卡二卡三乱码免费卡| 182午夜在线观看| 亚洲成人久久电影| 欧美成人激情| 97国产精东麻豆人妻电影 | 激情欧美丁香| 日韩精品无码一区二区三区免费| 51精品秘密在线观看| 成人av地址| 伊人色综合久久天天五月婷| 亚洲成av人片观看| 91麻豆精品国产91久久久更新资源速度超快 | 亚洲男人资源| 日日骚久久av| 久久动漫亚洲| 一二三四社区在线视频6| 日韩视频―中文字幕| 模特精品在线| 香蕉视频在线网站| 亚洲综合不卡| 日本一区二区三区免费观看| 香蕉视频国产精品| av成人app永久免费| 国产乱人伦真实精品视频| www.激情成人| 欧美xxxx少妇| 99久久国产免费免费| 国产精品五月天| 欧美极品videos大乳护士| 91偷拍精品一区二区三区| 国产精品高潮呻吟| 亚洲精品伊人| 女人床在线观看| 精品国产免费一区二区三区四区 | 91久久久久久久| 国产98色在线|日韩| 成年人视频免费在线播放| 精品成人在线观看| 国产精品久久久久av电视剧| 国产欧美精品一区二区三区-老狼| 亚洲国产欧美在线成人app | 成人免费黄色网址| 亚洲欧洲日产国产网站| 亚洲国产精品第一区二区| 国产视频三区| 97在线观看视频国产| 亚洲国产成人午夜在线一区 | 色综合www| 欧美男女交配视频| 欧美精品在线观看| 国产日韩欧美综合一区| 日韩视频在线直播| 欧美伦理视频在线观看| 欧美日本在线视频中文字字幕| 久久一二三国产| www.成人网| eeuss在线播放| 国产精品444| 欧美日韩一区二区在线播放| 午夜久久福利| av网址在线| 一本色道久久88亚洲精品综合| 在线精品国产成人综合| 久久婷婷国产综合精品青草 | 色与欲影视天天看综合网| 91麻豆文化传媒在线观看| 国产一区二区视频在线看| 亚洲免费看av| 国产精品亚洲激情| 欧美色精品在线视频| 日本中文字幕一区二区有限公司| 岛国av在线网站| 鲁一鲁一鲁一鲁一澡| 久久免费观看视频| 精品国产91久久久| 久久在线精品| 日本一区免费网站| 激情视频免费| 国产一区二区高清不卡| 亚洲成人久久电影| 99久久精品久久久久久清纯| 秋霞一区二区| 一区二区成人| 热re99久久精品国产99热| av在线不卡免费观看| 国产在线黄色片| 成人免费视频视频在| 精品国产污网站| 久久久久国产精品人| 中文字幕一区二区三三| 草美女在线观看| 91av在线免费播放| 5g国产欧美日韩视频| 精品一区二区三区四区在线| 国产精品久久久久久久久免费樱桃 | 欧美精品一区二区视频| 最近日韩中文字幕中文| 亚洲另类在线一区| 在线亚洲精品| 国产精品日韩精品在线播放| 国产美女极品在线| 中文字幕欧美日韩一区二区三区| 欧美精品videosex性欧美| 在线一区二区视频| 成人教育av在线| 综合激情视频| 欧美日韩伦理一区二区| 国产精品69页| 蜜桃av噜噜一区二区三区| 美日韩精品视频免费看| 欧美影视一区在线| 91在线精品一区二区| 欧美午夜免费影院| 99久热在线精品视频观看| 国产高清自拍视频在线观看| 波多野结衣之无限发射| 国产麻豆一区二区三区在线观看| 日韩视频在线观看免费| 678五月天丁香亚洲综合网| 国产精品色噜噜| 日韩精品电影一区亚洲| 亚洲免费福利一区|