日韩无码专区无码一级三级片|91人人爱网站中日韩无码电影|厨房大战丰满熟妇|AV高清无码在线免费观看|另类AV日韩少妇熟女|中文日本大黄一级黄色片|色情在线视频免费|亚洲成人特黄a片|黄片wwwav色图欧美|欧亚乱色一区二区三区

RELATEED CONSULTING
相關(guān)咨詢
選擇下列產(chǎn)品馬上在線溝通
服務(wù)時間:8:30-17:00
你可能遇到了下面的問題
關(guān)閉右側(cè)工具欄

新聞中心

這里有您想知道的互聯(lián)網(wǎng)營銷解決方案
想愛容易相處難:當(dāng)ASP.NETMVC愛上IoC

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

創(chuàng)新互聯(lián)-專業(yè)網(wǎng)站定制、快速模板網(wǎng)站建設(shè)、高性價比華池網(wǎng)站開發(fā)、企業(yè)建站全套包干低至880元,成熟完善的模板庫,直接使用。一站式華池網(wǎng)站制作公司更省心,省錢,快速模板網(wǎng)站建設(shè)找我們,業(yè)務(wù)覆蓋華池地區(qū)。費用合理售后完善,10多年實體公司更值得信賴。

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

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

下面是一個網(wǎng)站所用的一個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ù)中專門創(chuàng)建對應(yīng)于_jobService與_enterpriseService的實例。IoC容器會在運行時自動創(chuàng)建IJobService與IEnterpriseService的實例,并傳遞給EnterpriseController的構(gòu)造函數(shù)。

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

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

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

要想實現(xiàn)Controller的依賴注入,就需要讓IoC容器接管Controller的創(chuàng)建,而ASP.NET MVC 3中提供的IDependencyResolver接口就為實現(xiàn)這個提供了可能。所以,我們首先創(chuàng)建一個實現(xiàn)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 GetServices(Type serviceType)  
  16.     {  
  17.         return container.ResolveAll(serviceType);  
  18.     }  
  19. UnityDependencyResolver的作用就是調(diào)用IoC容器(這里是Unity)解析相應(yīng)類型的實例。創(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));  

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

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

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

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

     
     
     
     
    1. container.RegisterType(); 

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

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

    找不到IControllerActivator的實現(xiàn)實例,看來,創(chuàng)建Controller還需要這個東東。查看MVC的源代碼發(fā)現(xiàn)IControllerActivator的默認(rèn)實現(xiàn)是DefaultControllerActivator,但郁悶的是它竟然是private class,無法注冊它。別無選擇,只能自己實現(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ù)運行,又出現(xiàn)新的錯誤:

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

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

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

    [[40973]]

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

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

     
     
     
     
    1. No parameterless constructor defined for this object. 

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

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

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

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

    上面的代碼中,factory的類型是IControllerFactory,ControllerBuilder.GetControllerFactory()的作用是獲取IControllerFactory的實現(xiàn)實例,而實際是通過調(diào)用IDependencyResolver接口得到的(我們之前實現(xiàn)的UnityDependencyResolver接管了IDependencyResolver接口)。但我們沒有在IoC容器中注冊IControllerFactory,實際是由MVC返回IControllerFactory的默認(rèn)實現(xiàn)DefaultControllerFactory。從上面的代碼還可以看出,Controller實例的創(chuàng)建是通過調(diào)用IControllerFactory.CreateController()方法,所以,我們要在DefaultControllerFactory.CreateController()方法中尋找線索,對應(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的實例,進(jìn)一步查看其代碼:

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

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

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

     
     
     
     
    1. container.RegisterType(); 

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

    [[40974]]

    小結(jié)

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

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

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

    完整示例代碼下載

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


    本文標(biāo)題:想愛容易相處難:當(dāng)ASP.NETMVC愛上IoC
    本文鏈接:http://www.5511xx.com/article/cogjphh.html