ASP.NET MVC 控制器激活(一)


ASP.NET MVC 控制器激活(一)

前言

在路由的篇章中講解了路由的作用,講着講着就到了控制器部分了,從本篇開始來講解MVC中的控制器,控制器是怎么來的?MVC框架對它做了什么?以及前面有的篇幅所留的疑問將會在這部分里解決掉。

 

 

對於控制器激活的總結

 

總的來說控制器的激活過程有這么幾個步驟(部分):

 

1.根據當前路由信息獲取控制器名稱

2.獲取當前系統的控制器工廠(用來生成控制器)

  2.1   據控制器名稱生成和當前系統的請求上下文參數生成控制器類型(Type

     2.1.1 根據當前的路由信息判斷選擇控制器所在命名空間

     2.1.2 返回控制器類型(Type)

  2.2   根據控制器類型(Type)請求上下文參數生成控制器類型(IController)

2.3    返回控制器類型(IController)

3.獲取由控制器工廠生成的控制器(IController)

4.執行IController.Execute()

 

控制器的由來

前面都有講到MVC的入口在Module中,具體是在注冊路由的時候,默認的注冊MvcHandler作為請求處理類型,而控制器的就是在這里生產出來的,為什么說是生產?因為系統預先實現了一個控制器工廠類DefaultControllerFactory(如下的代碼結構),在控制器生成到執行的這個過程里涉及到眾多的類型和控制器的對象模型,這些內容在后面篇幅會一一講解。

DefaultControllerFactory類型的結構:

 1  public class DefaultControllerFactory : IControllerFactory  2  {  3  public DefaultControllerFactory();  4  public DefaultControllerFactory(IControllerActivator controllerActivator);  5 
 6  public virtual IController CreateController(RequestContext requestContext, string controllerName);  7  protected internal virtual IController GetControllerInstance(RequestContext requestContext, Type controllerType);  8  protected internal virtual SessionStateBehavior GetControllerSessionBehavior(RequestContext requestContext, Type controllerType);  9  protected internal virtual Type GetControllerType(RequestContext requestContext, string controllerName); 10  public virtual void ReleaseController(IController controller); 11     }

 

本篇先將上面總結中的2.1.2之前的部分粗略的講解一下,請先看如下圖:

 

如上圖,這里先要說的是控制器類型緩存對象ControllerTypeCache,ControllerTypeCache加載所有實現了IController接口的公共類並緩存在MVC-ControllerTypeCache.xml文件里。當然了這些都是框架所做的,我們只需了解一下,學習其中的思想就行了。

在請求到達默認請求處理程序的時候,由默認的控制器工廠DefaultControllerFactory來根據RouteData的DataToken【NameSpaces】里的定義的命名空間和Values【controller】的控制器名稱來進行判斷,具體怎么判斷的是由ControllerTypeCache對象來查詢匹配的。

先根據控制器名稱查詢緩存中是否有對應此名稱的控制器,如果有則存放在 ILookup<string, Type>類型對象中,然后根據RouteData的DataToken【NameSpaces】里的定義的命名空間來和ILookup<string, Type>對象中的控制器類型所在命名空間進行比對,如果是相同的則添加此類型到返回集合,如果不相同則繼續用RouteData的DataToken【NameSpaces】剩下的命名空間值挨個的進行比對。

根據返回的類型集合,如果總數為0返回空,總數為1返回此集合中的類型,如果大於1則會引發CreateAmbiguousControllerException類型的異常。

在此時DefaultControllerFactory中已經獲取到了控制器類型(Type)。

在總結中2.2所指部分為IControllerActivator接口類型的實現。

 1     // 摘要:
 2     //     對使用依賴項注入實例化控制器的方式進行精細控制。
 3     public interface IControllerActivator
 4     {
 5         // 摘要:
 6         //     在類中實現時創建控制器。
 7         //
 8         // 參數:
 9         //   requestContext:
10         //     請求上下文。
11         //
12         //   controllerType:
13         //     控制器類型。
14         //
15         // 返回結果:
16         //     創建的控制器。
17         IController Create(RequestContext requestContext, Type controllerType);

這部分的實現,可以注入到控制器工廠,而實現的內部依然有可擴展注入的地方,在MVC框架中有默認的實現,我們先來看一下2.2部分之后的實現概念圖:

獲取到了Controller的Type過后,DefaultControllerFactory就可以根據Type來創建Controller,然而在MVC框架的設計中,【根據ControllerType創建Controller的方式】是不會放在DefaultControllerFactory中的,而是通過MVC框架中實現了IControllerActivator接口類型的默認實現類DefaultControllerActivator類型來進行創建IController的,而在DefaultControllerActivator中又是通過DependencyResolver類型來創建一個IDependencyResolver接口的默認實現類來實現的。

在IDependencyResolver接口中,有個GetService()方法,這個方法就是最終要創建類型所用到的方式,也可以自定義來實現,這也是擴展點之一。說回接口類型,MVC中有個默認的實現了IDependencyResolver接口的類型DefaultDependencyResolver,在DefaultDependencyResolver類型中GetService()方法的默認實現方式Activator.CreateInstance(serviceType);也就是正常通過反射來創建類型的。

看一下由Handler到Icontroller的一個過程圖:

上面的這些以及前面篇幅所講,都是MVC默認實現的方式,每個部分都可以自定義來擴展,MvcHandler、DefaultControllerFactory、DefaultDependencyResolver等等這些類型。

會在后面的篇幅中說明在激活控制器的過程中所有可注入擴展點的。

 

 

 

 

作者:金源

出處:http://www.cnblogs.com/jin-yuan/

本文版權歸作者和博客園共有,歡迎轉載,但未經作者同意必須保留此段聲明,且在文章頁面


免責聲明!

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



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