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


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

     我們可以在三個階段使用IoC實現上面所說的解耦操作,首先需要簡單介紹一下默認情況下Controller的激活過程:

  1. 用戶發送請求黑ASP.NET,路由系統對請求進行解析,根據注冊的路由規則對請求進行匹配,解析出Controller和Action的名稱等信息。
  2. 將解析出的信息交給一個MvcRouteHandler對象進行處理,MvcHttpHandler中存在以個ControllerFactory成員,如果構造函數中沒有提供一個實現IControllerFactory接口的對象,則默認構造函數通過調用ControllerBuilder.Current.GetControllerFactory()獲取一個這樣的對象。
  3. 系統調用上文對象中德GetHttpHandler獲得了一個實現了IHttpHandler接口的MvcHandler對象最終處理請求。
  4. 在MvcHandler中調用BeginProcessRequest方法繼續處理請求,方法中從1中解析的信息中獲得Controller和Action的信息,而后利用2種的IControllerFactory對象激活Controller對象,並最終執行相應的Action。

第一種方法

      由上文2種可知,我們可以創建自己的IControllerFactory對象實現依賴注入,然而我們可以通過直接繼承DefaultControllerFactory並重寫GetControllerInstance方法來實現,這樣可以免去重新實現其他一些功能的工作。

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

namespace UnitySample
{
    public class UnityControllerFactory:DefaultControllerFactory
    {
        private IUnityContainer container;


        public UnityControllerFactory(IUnityContainer container)
        {
            this.container = container;
        }
        protected override IController GetControllerInstance(RequestContext requestContext, Type controllerType)
        {
            return null == controllerType ? null : (IController)this.container.Resolve(controllerType);
            //return base.GetControllerInstance(requestContext, controllerType);
        }
    }
}

我們可以在App_Start中使用ControllerBuilder設置系統使用這個ControllerFactory

IUnityContainer container = new UnityContainer();
container.RegisterType<IXXXRepository, XXXRepository>();
UnityControllerFactory factory = new UnityControllerFactory(container);
ControllerBuilder.Current.SetControllerFactory(factory);
 

第二種方法

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

namespace UnitySample
{
    public class UnityControllerActivator:IControllerActivator
    {
        private IUnityContainer container;


        public UnityControllerActivator(IUnityContainer container)
        {
            this.container = container;
        }
        public IController Create(RequestContext requestContext, Type controllerType)
        {
            return controllerType == null ? null : (IController)container.RegisterType(controllerType);
        }
    }
}

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

IUnityContainer container = new UnityContainer();
container.RegisterType<IXXXRepository, XXXRepository>();
//UnityControllerFactory factory = new UnityControllerFactory(container);
IControllerActivator controllerActivator = new UnityControllerActivator(container);
DefaultControllerFactory defaultFactory = new DefaultControllerFactory(controllerActivator);
ControllerBuilder.Current.SetControllerFactory(defaultFactory);

第三種方法

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

namespace UnitySample
{
    public class UnityDependencyResolver:IDependencyResolver
    {
        private IUnityContainer container;


        public UnityDependencyResolver(IUnityContainer container)
        {
            this.container = container;
        }

        public object GetService(Type serviceType)
        {
            return container.Resolve(serviceType);
        }

        public IEnumerable<object> GetServices(Type serviceType)
        {
            return container.ResolveAll(serviceType);
        }
    }
}

 

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

IUnityContainer container = new UnityContainer();
container.RegisterType<IXXXRepository, XXXRepository>();
UnityDependencyResolver resolver = new UnityDependencyResolver(container);
DependencyResolver.SetResolver(resolver);


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM