<output id="qn6qe"></output>

    1. <output id="qn6qe"><tt id="qn6qe"></tt></output>
    2. <strike id="qn6qe"></strike>

      亚洲 日本 欧洲 欧美 视频,日韩中文字幕有码av,一本一道av中文字幕无码,国产线播放免费人成视频播放,人妻少妇偷人无码视频,日夜啪啪一区二区三区,国产尤物精品自在拍视频首页,久热这里只有精品12

      ASP.NET MVC是如何運行的(3): Controller的激活

      ASP.NET MVC的URL路由系統(tǒng)通過注冊的路由表對HTTP請求進行解析從而得到一個用于封裝路由數(shù)據(jù)的RouteData對象,而這個過程是通過自定義的UrlRoutingModule對HttpApplication的PostResolveRequestCache事件進行注冊實現(xiàn)的。RouteData中已經(jīng)包含了目標Controller的名稱,現(xiàn)在我們來進一步分析真正的Controller對象是如何被激活的。我們首先需要了解一個類型為MvcRouteHandler的類型。

      一、MvcRouteHandler

      通過前面的介紹我們知道繼承自RouteBase的Route類型具有一個類型為IRouteHandler接口的屬性RouteHandler,它主要的用途就是用于根據(jù)指定的請求上下文(通過一個RequestContext對象表示)來獲取一個HttpHandler對象。當GetRouteData方法被執(zhí)行后,Route的RouteHandler屬性值將反映在得到的RouteData的同名屬性上。在默認的情況下,Route的RouteHandler屬性是一個MvcRouteHandler對象,如下的代碼片斷反映了這一點。

         1: public class Route : RouteBase
         2: {
         3:     //其他成員
         4:     public IRouteHandler RouteHandler { get; set; }
         5:     public Route()
         6:     {
         7:         //其他操作
         8:         this.RouteHandler = new MvcRouteHandler();
         9:     }
        10: }

      對于我們這個“迷你版”的ASP.NET MVC框架來說,MvcRouteHandler是一個具有如下定義的類型。在實現(xiàn)的GetHttpHandler方法中,它直接返回一個MvcHandler對象。

         1: public class MvcRouteHandler: IRouteHandler
         2: {
         3:     public IHttpHandler GetHttpHandler(RequestContext requestContext)
         4:     {
         5:         return new MvcHandler(requestContext);
         6:     }
         7: }

      二、MvcHandler

      在前面的內(nèi)容中我們已經(jīng)提到整個ASP.NET MVC框架是通過自定義的HttpModule和HttpHandler對象ASP.NET進行擴展實現(xiàn)的。這個自定義HttpModule我們已經(jīng)介紹過了,就是UrlRoutingModule,而這個自定義的HttpHandler則是我們要重點介紹的MvcHandler。

      UrlRoutingModule在通過路由表解析HTTP請求得到一個用于封裝路由數(shù)據(jù)的RouteData后,或調(diào)用其RouteHandler的GetHttpHandler方法得到HttpHandler對象并注冊到當前的HTTP上下文。由于RouteData的RouteHandler來源于對應(yīng)Route對象的RouteHandler,而后者在默認的情況下是一個MvcRouteHandler對象,所以默認情況下用于處理HTTP請求的就是這么一個MvcHandler對象。MvcHandler實現(xiàn)了對Controller對象的激活和對相應(yīng)Action方法的執(zhí)行。

      下面的的代碼片斷體現(xiàn)了MvcHandler的整個定義,它具有一個類型為RequestContext的屬性表示被處理的當前請求上下文,該屬性在構(gòu)造函數(shù)指定。在實現(xiàn)的ProcessRequest中實現(xiàn)了對Controller對象的激活和執(zhí)行。

         1: public class MvcHandler: IHttpHandler
         2: {
         3:     public bool IsReusable
         4:     {
         5:         get{return false;}
         6:     }
         7:     public RequestContext RequestContext { get; private set; }
         8:     public MvcHandler(RequestContext requestContext)
         9:     {
        10:         this.RequestContext = requestContext;
        11:     }
        12:     public void ProcessRequest(HttpContext context)
        13:     {
        14:         string controllerName = this.RequestContext.RouteData.Controller;
        15:         IControllerFactory controllerFactory = ControllerBuilder.Current.GetControllerFactory();
        16:         IController controller = controllerFactory.CreateController(this.RequestContext, controllerName);
        17:         controller.Execute(this.RequestContext);
        18:     }
        19: }

      三、Controller與ContrllerFactory

      我們?yōu)镃ontroller定義了一個接口IController,如下面的代碼片斷所示,該接口具有唯一的方法Execute在MvcHandler的ProcessRequest方法中被執(zhí)行,而傳入該方法的參數(shù)時表示當前請求上下文的RequestContext對象。

         1: public interface IController
         2: {
         3:     void Execute(RequestContext requestContext);
         4: }

      從MvcHandler的定義我們可以看到Controller對象的激活是通過工廠模式實現(xiàn)的,我們?yōu)镃ontroller工廠定義了一個具有如下定義的IControllerFactory接口。IControllerFactory通過CreateController方法根據(jù)傳入的請求上下文和Controller的名稱來激活相應(yīng)的Controller對象。

         1: public interface IControllerFactory
         2: {
         3: IController CreateController(RequestContext requestContext, string controllerName);
         4: }

      在MvcHandler的ProcessRequest方法中,它通過ControllerBuilder的靜態(tài)屬性Current得到當前的ControllerBuilder對象,并調(diào)用GetControllerFactory方法獲得當前的ControllerFactory。然后通過從自己的RequestContext中提取的RouteData獲得Controller的名稱,最后將它連同RequestContext一起作為ContollerFactory的CreateController方法的參數(shù)進而創(chuàng)建具體的Controller對象。

      ControllerBuilder的整個定義如下面的代碼片斷所示,表示當前ControllerBuilder的靜態(tài)只讀屬性的Current在靜態(tài)構(gòu)造函數(shù)中被創(chuàng)建。SetControllerFactory和GetControllerFactory方法用于ContorllerFactory的注冊和獲取。而類型為HashSet<string>的DefaultNamespaces屬性表示默認的命名空間列表,這是為了最終解析Controller類型的需要。

         1: public class ControllerBuilder
         2: {
         3:     private Func<IControllerFactory> factoryThunk;
         4:     static ControllerBuilder()
         5:     {
         6:         Current = new ControllerBuilder();
         7:     }
         8:     public ControllerBuilder()
         9:     {
        10:         this.DefaultNamespaces = new HashSet<string>();
        11:     }
        12:     public static ControllerBuilder Current { get; private set; }
        13:     public IControllerFactory GetControllerFactory()
        14:     {
        15:         return factoryThunk();
        16:     }
        17:     public void SetControllerFactory(IControllerFactory controllerFactory)
        18:     {
        19:         factoryThunk = () => controllerFactory;
        20:     }
        21:     public HashSet<string> DefaultNamespaces { get; private set; }
        22: }

      在回頭看看我們之前建立在我們自定義ASP.NET MVC框架的Web應(yīng)用,我們就是通過當前的ControllerBuilder進行ControllerFactory的注冊和默認命名空間的指定的。如下面的代碼片斷所示,我們注冊的ControllerFactory的類型為DefaultControllerFactory。

         1: public class Global : System.Web.HttpApplication
         2: {
         3:     protected void Application_Start(object sender, EventArgs e)
         4:     {            
         5:         //其他操作
         6:         ControllerBuilder.Current.SetControllerFactory(new DefaultControllerFactory());
         7:         ControllerBuilder.Current.DefaultNamespaces.Add("WebApp");
         8:     }
         9: }

      作為默認ControllerFactory的DefualtControllerFactory類型定義如下。激活Controller類型的前提是能夠正確解析出Controller的真實類型。作為CreateController方法輸入?yún)?shù)的controllerName僅僅表示Controller的名稱,我們需要加上Controller字符后綴作為類型名稱。此外我們還需要得到類型的命名空間,而命名空間具有兩個來源,即RouteData和當前ControllerBuilder。在DefualtControllerFactory初始化過程中,我們通過BuildManager加載所有應(yīng)用的程序集,并加載所有實現(xiàn)了接口IController的類型并保存起來,而在CreateController方法中根據(jù)Controller的名稱和命名空間從保存的Controller類型列表中得到對應(yīng)的Controller類型,并通過反射的方式創(chuàng)建它。

         1: public class DefaultControllerFactory : IControllerFactory
         2: {
         3:     private List<Type> controllerTypes = new List<Type>();
         4:     public DefaultControllerFactory()
         5:     {
         6:         foreach (Assembly assembly in BuildManager.GetReferencedAssemblies())
         7:         {
         8:             foreach (Type type in assembly.GetTypes().Where(type => typeof(IController).IsAssignableFrom(type)))
         9:             {
        10:                 controllerTypes.Add(type);
        11:             }
        12:         }
        13:     }
        14:     public IController CreateController(RequestContext requestContext, string controllerName)
        15:     {
        16:         string typeName = controllerName + "Controller";
        17:         List<string> namespaces = new List<string>();
        18:         namespaces.AddRange(requestContext.RouteData.Namespaces);
        19:         namespaces.AddRange(ControllerBuilder.Current.DefaultNamespaces);
        20:         foreach (var ns in namespaces)
        21:         {
        22:             string controllerTypeName = string.Format("{0}.{1}", ns, typeName);
        23:             Type controllerType = controllerTypes.FirstOrDefault(type => string.Compare(type.FullName, controllerTypeName, true) == 0);
        24:             if (null != controllerType)
        25:             {
        26:                 return (IController)Activator.CreateInstance(controllerType); 
        27:             }
        28:         }            
        29:         return null;
        30:     }
        31: }

      上面我們詳細地介紹了Controller的激活原理,我們現(xiàn)在講關(guān)注點返回到Controller自身。通過實現(xiàn)IContrller接口,我們?yōu)榫哂械腃ontroller定義了一個具有如下定義的ControllerBase抽象基類。從中我們可以看到在實現(xiàn)的Execute方法中,ControllerBase通過一個實現(xiàn)了接口IActionInvoker的對象完成了針對Action方法的執(zhí)行。

         1: public abstract class ControllerBase: IController
         2: {
         3:     protected IActionInvoker ActionInvoker { get; set; }
         4:     public ControllerBase()
         5:     {
         6:         this.ActionInvoker = new ControllerActionInvoker();
         7:     }
         8:     public void Execute(RequestContext requestContext)
         9:     {
        10:         ControllerContext context = new ControllerContext { RequestContext = requestContext, Controller = this };
        11:         string actionName = requestContext.RouteData.ActionName;
        12:         this.ActionInvoker.InvokeAction(context, actionName);
        13:     }
        14: }

       

      ASP.NET MVC是如何運行的[1]: 建立在“偽”MVC框架上的Web應(yīng)用
      ASP.NET MVC是如何運行的[2]: URL路由
      ASP.NET MVC是如何運行的[3]: Controller擊激活
      ASP.NET MVC是如何運行的[4]: Action的執(zhí)行

      posted @ 2012-03-12 09:19  Artech  閱讀(16232)  評論(16)    收藏  舉報
      主站蜘蛛池模板: av在线播放无码线| 色五月丁香六月欧美综合| 亚洲av日韩av永久无码电影| 虎白女粉嫩尤物福利视频| 人妻少妇偷人精品一区| 国产熟睡乱子伦视频在线播放| 日本高清中文字幕免费一区二区| 亚洲码欧洲码一二三四五| 青青草一区二区免费精品| 国产成人一区二区不卡| 亚洲av综合久久成人网| 亚洲2区3区4区产品乱码2021| 国产美女69视频免费观看| 日韩老熟女av搜索结果| 成人av一区二区三区| 四虎永久精品免费视频| 国产精品中文av专线| 亚洲国产欧美不卡在线观看| 国产日韩精品视频无码| 中国CHINA体内裑精亚洲日本| 久久av高潮av无码av喷吹| 精品偷拍一区二区三区在| 西西人体44WWW高清大胆| 精品国产精品三级精品av网址| 国产免费午夜福利在线播放| 国产一卡2卡三卡4卡免费网站| 林甸县| 成人午夜伦理在线观看| 人妻系列无码专区免费 | 精品免费看国产一区二区| 嫩江县| 亚洲男人第一无码av网| 色婷婷综合久久久久中文字幕| 欧美国产日产一区二区| 黑人精品一区二区三区不| 国产人免费人成免费视频| 中文字幕在线视频不卡一区二区| 久久国产精品伊人青青草| 精品乱码一区二区三四区视频| 日本韩无专砖码高清观看| 国产91久久精品一区二区|