在ASP.NET MVC中使用Unity進行依賴注入的三種方式

在ASP.NET MVC4中,爲了在解開Controller和Model的耦合,咱們一般須要在Controller激活系統中引入IoC,用於處理用戶請求的 Controller,讓Controller依賴於ModelRepository的抽象而不是它的實現。ide

咱們能夠在三個階段使用IoC實現上面所說的解耦操做,首先須要簡單介紹一下默認狀況下Controller的激活過程:函數

一、用戶發送請求黑ASP.NET,路由系統對請求進行解析,根據註冊的路由規則對請求進行匹配,解析出Controller和Action的名稱等信息。ui

二、將解析出的信息交給一個MvcRouteHandler對象進行處理,MvcHttpHandler中存在以個ControllerFactory成員,若是構造函數中沒有提供一個實現IControllerFactory接口的對象,則默認構造函數經過調用ControllerBuilder.Current.GetControllerFactory()獲取一個這樣的對象。this

三、系統調用上文對象中德GetHttpHandler得到了一個實現了IHttpHandler接口的MvcHandler對象最終處理請求。spa

四、在 MvcHandler中調用BeginProcessRequest方法繼續處理請求,方法中從1中解析的信息中得到Controller和Action 的信息,然後利用2種的IControllerFactory對象激活Controller對象,並最終執行相應的Action。code

第一種方法對象

由上文2種可知,咱們能夠建立本身的IControllerFactory對象實現依賴注入,然而咱們能夠經過直接繼承 DefaultControllerFactory並重寫GetControllerInstance方法來實現,這樣能夠免去從新實現其餘一些功能的工做。blog

如下是使用Unity建立的繼承自DefaultControllerFactory的UnityControllerFactory的簡單示例:繼承

 1 namespace UnitySample
 2 
 3 {
 4 
 5 public class UnityControllerFactory:DefaultControllerFactory
 6 
 7 {
 8 
 9 private IUnityContainer container;
10 
11 public UnityControllerFactory(IUnityContainer container)
12 
13 {
14 
15 this.container = container;
16 
17 }
18 
19 protected override IController GetControllerInstance(RequestContext requestContext, Type controllerType)
20 
21 {
22 
23 return null == controllerType ? null : (IController)this.container.Resolve(controllerType);
24 
25 //return base.GetControllerInstance(requestContext, controllerType);
26 
27 }
28 
29 }
30 
31 }

 

咱們能夠在App_Start中使用ControllerBuilder設置系統使用這個ControllerFactory接口

1 IUnityContainer container = new UnityContainer();
2 
3 container.RegisterType();
4 
5 UnityControllerFactory factory = new UnityControllerFactory(container);
6 
7 ControllerBuilder.Current.SetControllerFactory(factory);

 

第二種方法

上文中繼承的DefaultControllerFactory中,使用一個ControllerActivator的成員來實現對 Controller的激活,若是建立對象中沒有提供一個IControllerActivator對象,則提供一個默認實現了 IControllerActivator的DefaultControllerActivator對象這個類型,這個接口中存在用於建立 Controller對象的Create方法,在DefaultControllerFactory中有存在一個 IControllerActivator類型的構造方法來制定它。因此咱們可使用一個自定義的實現自IControllerActivator藉口的對象來進行依賴注入。

 1 namespace UnitySample
 2 
 3 {
 4 
 5 public class UnityControllerActivator:IControllerActivator
 6 
 7 {
 8 
 9 private IUnityContainer container;
10 
11 public UnityControllerActivator(IUnityContainer container)
12 
13 {
14 
15 this.container = container;
16 
17 }
18 
19 public IController Create(RequestContext requestContext, Type controllerType)
20 
21 {
22 
23 return controllerType == null ? null : (IController)container.RegisterType(controllerType);
24 
25 }
26 
27 }
28 
29 }

 

修改方法1中在App_Start中的代碼,使用這個ControllerActivator:

 1 IUnityContainer container = new UnityContainer();
 2 
 3 container.RegisterType();
 4 
 5 //UnityControllerFactory factory = new UnityControllerFactory(container);
 6 
 7 IControllerActivator controllerActivator = new UnityControllerActivator(container);
 8 
 9 DefaultControllerFactory defaultFactory = new DefaultControllerFactory(controllerActivator);
10 
11 ControllerBuilder.Current.SetControllerFactory(defaultFactory);

 

第三種方法

如同DefaultControllerFactory類中同樣,在DefaultControllerActivator中也存在一個包含一個參數(類型爲IDependencyResolver)的構造方法和一個沒有參數的構造方法,默認狀況下DefaultControlerFactory使用無參構造函數實例化一個DefaultControllerActivator對象,這種狀況下提供一個默認的IDependencyResolver 對象。因此咱們就一樣可使用一個自定義的IDependencyResolver類實現依賴注入。在IDependencyResolver接口中存在方法GetService和GetServices來對具體的類型進行解析

 1 namespace UnitySample
 2 
 3 {
 4 
 5 public class UnityDependencyResolver:IDependencyResolver
 6 
 7 {
 8 
 9 private IUnityContainer container;
10 
11 public UnityDependencyResolver(IUnityContainer container)
12 
13 {
14 
15 this.container = container;
16 
17 }
18 
19 public object GetService(Type serviceType)
20 
21 {
22 
23 return container.Resolve(serviceType);
24 
25 }
26 
27 public IEnumerable<object>GetServices(Type serviceType)
28 
29 {
30 
31 return container.ResolveAll(serviceType);
32 
33 }
34 
35 }
36 
37 }

 

修改App_Strat中的方法,使用這個自定義的DependencyResolver:

1 IUnityContainer container=new UnityContainer();
2 
3 container.Register Type<IXXXRepository,XXXRepository>();
4 
5 UnityDependencyResolver resolver=new UnityDependencyResolver(container);
6 
7 DependencyResolver.SetResolver(resolver)
相關文章
相關標籤/搜索