程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> .NET網頁編程 >> ASP.NET >> 關於ASP.NET >> ASP.NET MVC Controller激活系統詳解:IoC的應用[下篇]

ASP.NET MVC Controller激活系統詳解:IoC的應用[下篇]

編輯:關於ASP.NET

[上篇]除了通過自定義ControllerFactory的方式引入IoC之外,在使用默認DefaultControllerFactory情況下也可以通過一些擴展使基於IoC的Controller激活成為可能。主要的方式就是自定義ControllerActivator和 DependencyResolver。

四、ControllerActivator V.S. DependencyResolver

如下面的代碼片斷所示,DefaultControllerFactory具有兩個構造函數重載,其中一個具有一個類型為IControllerActivator接口的參數,我們將實現了該接口得類型統稱為ControllerActivator。

   1: public class DefaultControllerFactory : IControllerFactory
2: {
3: //其他成員
4: public DefaultControllerFactory();
5: public DefaultControllerFactory(IControllerActivator controllerActivator);
6: }

顧名思義,ControllerActivator就是Controller的“激活器”,Controller的激活實現在唯一的Create方法中。如下面的代碼所示,該方法具有兩個參數(requestContext和controllerType),分別代表當前請求上下文和解析出來的目標Controller的類型。

   1: public interface IControllerActivator
2: {
3: IController Create(RequestContext requestContext, Type controllerType);
4: }

在默認的情況下(調用DefaultControllerFactory默認構造函數或者指定的參數為Null),Controller激活系統 會默認使用一個類型為DefaultControllerActivator的對象。如下面的代碼片斷所示,DefaultControllerActivator是一個實現了IControllerActivator私有類型而已,我們不能直接通過編程的方式使用它。

   1: private class DefaultControllerActivator : IControllerActivator
2: {
3: public DefaultControllerActivator();
4: public DefaultControllerActivator(IDependencyResolver resolver);
5: public IController Create(RequestContext requestContext, Type controllerType);
6: }

DefaultControllerActivator的構造函數具有一個類型為IDependencyResolver的參數,這是一個重要的接口,我們將實現了該接口的類型統稱為DependencyResolver。。如下面的代碼片斷所示,IDependencyResolver接口具有兩個方法GetService和GetServices,用於根據指定的類型獲取單個或者多個實例。實際上DefaultControllerActivator就是通過調用GetService方法獲取具體的Controller對象的

   1: public interface IDependencyResolver
2: {
3: object GetService(Type serviceType);
4: IEnumerable<object> GetServices(Type serviceType);
5: }

如果在構造DefaultControllerActivator對象的時候傳入的參數為Null,那麼Controller激活系統會使用通過DependencyResolver的靜態只讀屬性Current表示DependencyResolver。需要提醒的是,DependencyResolver類型沒有實現IDependencyResolver接口,而是對一個實現了IDependencyResolver接口類型對象的封裝。

   1: public class DependencyResolver
2: {
3: private static DependencyResolver _instance;
4:
5: public void InnerSetResolver(object commonServiceLocator);
6: public void InnerSetResolver(IDependencyResolver resolver);
7: public void InnerSetResolver(Func<Type, object> getService, Func<Type, IEnumerable<object>> getServices);
8:
9: public static void SetResolver(object commonServiceLocator);
10: public static void SetResolver(IDependencyResolver resolver);
11: public static void SetResolver(Func<Type, object> getService, Func<Type, IEnumerable<object>> getServices);
12:
13: public static IDependencyResolver Current { get; }
14: public IDependencyResolver InnerCurrent { get; }
15: }

這個被封裝的DependencyResolver(指實現了接口IDependencyResolver的某個類型的類型,不是指DependencyResolver類型的對象,對於後者我會采用“DependencyResolver類型對象”的說法)通過只讀屬性InnerCurrent表示,而三個InnerSetResolver方法重載用於初始化改屬性。靜態字段_instance表示當前的DependencyResolver類型對象,靜態只讀屬性Current則表示該對象內部封裝的DependencyResolver對象,而它通過三個靜態的SetResolver進行初始化。

如果我們不曾通過調用DependencyResolver的靜態方法SetResolver通過Current屬性表示的當前DependencyResolver進行顯示設置,該屬性默認返回一個DefaultDependencyResolver對象。如下面的代碼片斷所示,DefaultDependencyResolver是一個實現了IDependencyResolver接口的私有類型,在實現的GetService方法中,它直接通過根據指定的類型以反射的形式創建相應的對象並返回,所以前面我們說DefaultControllerFactory根據解析出來的Controller類型以反射的形式創建對應的實例在這裡得到了印證。至於GetServices方法則返回一個空對象集合。

   1: private class DefaultDependencyResolver : IDependencyResolver
2: {
3: public object GetService(Type serviceType)
4: {
5: if (serviceType.IsInterface || serviceType.IsAbstract)
6: {
7: return null;
8: }
9: try
10: {
11: return Activator.CreateInstance(serviceType);
12: }
13: catch
14: {
15: return null;
16: }
17: }
18:
19: public IEnumerable<object> GetServices(Type serviceType)
20: {
21: return Enumerable.Empty<object>();
22: }
23: }

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved