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

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

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

      ASP.NET MVC三個重要的描述對象:ControllerDescriptor和ActionDescriptor的創建

      不論是用于描述Controller的ControllerDescriptor,還是用于描述Action方法的ActionDescriptor,都具有同步和異步兩個版本,那么這些不同類型的ControllerDescriptor的ActionDescriptor是在什么情況下創建的呢?

      一、ControllerActionInvoker與AsyncControllerActionInvoker

      ControllerDescriptor的創建設計到一個重要的名為ActionInvoker的組件,顧名思義,ActionInvoker專門用于Action方法的執行。我們會在本書第7章“Action方法的執行”中對ActionInvoker進行深入介紹,在這里我們只需要對其作一個簡單的了解。

      ActionInvoker實現了具有如下定義的IActionInvoker接口,唯一的方法實現了對指定Action方法的執行,而作為Controller的默認基類的Controller具有一個ActionInvoker屬性,該屬性表示的ActionInvoker被真正用于定義在該Controller類型中的所有Action方法的執行。

         1: public interface IActionInvoker
         2: {
         3:     bool InvokeAction(ControllerContext controllerContext, string actionName);
         4: }
         5:  
         6: public abstract class Controller
         7: {   
         8:     //其它成員
         9:     public IActionInvoker ActionInvoker { get; set; }
        10: }

      而具有如下定義的System.Web.Mvc.Async.IAsyncActionInvoker接口是ActionInvoker的異步版本。IAsyncActionInvoker繼承了IActionInvoker接口,并在此基礎上定義了兩個BeginInvokeAction/EndInvokeAction方法用于Action方法的異步執行。

         1: public interface IAsyncActionInvoker : IActionInvoker
         2: {
         3:     IAsyncResult BeginInvokeAction(ControllerContext controllerContext,  string actionName, AsyncCallback callback, object state);
         4:     bool EndInvokeAction(IAsyncResult asyncResult);
         5: }

      ASP.NET MVC真正用于Action方法同步和異步執行的ActionInvoker分別是ControllerActionInvokerAsyncControllerActionInvoker。如下面的代碼片斷所示,ControllerActionInvoker定義了一個受保護的方法GetControllerDescriptor用于根據指定的Controller上下文獲取相應的ControllerDescriptor,它的子類AsyncControllerActionInvoker對這個方法進行了重寫。

         1: public class ControllerActionInvoker : IActionInvoker
         2: {
         3:     //其它成員
         4:     protected virtual ControllerDescriptor GetControllerDescriptor( ControllerContext controllerContext);
         5: }
         6:  
         7: public class AsyncControllerActionInvoker : ControllerActionInvoker,  IAsyncActionInvoker, IActionInvoker
         8: {
         9:     //其它成員
        10:     protected override ControllerDescriptor GetControllerDescriptor( ControllerContext controllerContext);
        11: }

      我們所有要了解的是在默認情況下(沒有對Controller類型的ActionInvoker屬性進行顯式設置)采用的ActionInvoker類型是哪個。ASP.NET MVC對Conroller采用的ActionInvoker類型的選擇機制是這樣的:

      • 通過當前的DependencyResolver以IAsyncActionInvoker接口去獲取注冊的ActionInvoker,如果返回對象不為Null,則將其作為默認的ActionInvoker
      • 通過當前的DependencyResolver以IActionInvoker接口去獲取注冊的ActionInvoker,如果返回對象不為Null,則將其作為默認的ActionInvoker
      • 創建AsyncControllerActionInvoker對象作為默認的ActionInvoker

      在默認的情況下,當前的DependencyResolver直接通過對指定的類型進行反射來提供對應的實例對象,所以對于前面兩個步驟返回的對象均為Null,所以默認創建出來的ActionInvoker類型為AsyncControllerActionInvoker。我們可以通過如下一個簡單的實例來驗證這一點。在通過Visual Studio的ASP.NET MVC項目模板創建的空Web應用中,我們創建了如下一個默認的HomeController,在Action方法Index中直接通過ContentResult將ActionInvoker屬性的類型名稱呈現出來。

         1: public class HomeController : Controller
         2: {  
         3:     public ActionResult Index()
         4:     {
         5:         return Content("默認ActionInvoker類型:" + this.ActionInvoker.GetType().FullName);
         6:     }
         7: }   

      當運行該Web應用時,會在瀏覽器上產生如下的輸出結果,我們可以清楚地看到默認采用的ActionInvoker類型正是AsyncControllerActionInvoker。

         1: 默認ActionInvoker類型:System.Web.Mvc.Async.AsyncControllerActionInvoker

      為了進一步驗證基于DependencyResolver對ActionInvoker的提供機制,我們將在《ASP.NET MVC Controller激活系統詳解:IoC的應用[下篇]》創建的基于Ninject的自定義NinjectDependencyResolver應用在這里。如下面的代碼片斷所示,在初始化NinjectDependencyResolver的時候,我們將IActionInvoker和IAsyncActionInvoker影射到兩個自定義ActionInvoker類型,即FooActionInvoker和FooAsyncActionInvoker,它們分別繼承自ControllerActionInvoker和AsyncControllerActionInvoker。

         1: public class NinjectDependencyResolver : IDependencyResolver
         2: {
         3:     public IKernel Kernel { get; private set; }
         4:     public NinjectDependencyResolver()
         5:     {
         6:         this.Kernel = new StandardKernel();
         7:         AddBindings();
         8:     }
         9:     private void AddBindings()
        10:     {
        11:         this.Kernel.Bind<IActionInvoker>().To<FooActionInvoker>();
        12:         this.Kernel.Bind<IAsyncActionInvoker>().To<FooAsyncActionInvoker>();
        13:     }
        14:     public object GetService(Type serviceType)
        15:     {
        16:         return this.Kernel.TryGet(serviceType);
        17:     }
        18:     public IEnumerable<object> GetServices(Type serviceType)
        19:     {
        20:         return this.Kernel.GetAll(serviceType);
        21:     }
        22: }
        23: public class FooActionInvoker : ControllerActionInvoker
        24: {}
        25: public class FooAsyncActionInvoker : AsyncControllerActionInvoker
        26: {}

      在Global.asax中對NinjectDependencyResolver進行注冊后運行我們的程序,會在瀏覽器中得到如下的輸出結果。IAsyncActionInvoker和FooAsyncActionInvoker進行了影射,NinjectDependencyResolver可以通過IAsyncActionInvoker提供一個FooAsyncActionInvoker實例。

         1: 默認ActionInvoker類型:Artech.Mvc.FooAsyncActionInvoker

      現在我們對NinjectDependencyResolver的定義稍加修改,將針對IAsyncActionInvoker接口的類型影射刪除,只保留針對IActionInvoker的映射。

         1: public class NinjectDependencyResolver : IDependencyResolver
         2: {
         3:     //其它成員
         4:     private void AddBindings()
         5:     {
         6:         this.Kernel.Bind<IActionInvoker>().To<FooActionInvoker>();
         7:         //this.Kernel.Bind<IAsyncActionInvoker>().To<FooAsyncActionInvoker>();
         8:     }
         9: }

      再次運行我們的程序則會得到如下的輸出結果。由于NinjectDependencyResolver只能通過IActionInvoker接口提供具體的ActionInvoker,所以最終被創建的是一個FooActionInvoker對象。這個實例演示告訴我們:當我們需要使用到自定義的ActionInvoker的時候,可以通過自定義DependencyResolver以IoC的方式提供具體的ActionInvoker實例。

         1: 默認ActionInvoker類型:Artech.Mvc.FooActionInvoker

      二、ActionInvoker與ControllerDescriptor/ActionDescriptor

      ControllerDescriptor和ActionDescriptor最終是為Model綁定服務的,而Model綁定是Action執行的一個環節,所以ControllerDescriptor最終是由相應的ActionInvoker創建的。總的來說,用于同步Action執行的ControllerActionInvoker創建ReflectedControllerDescriptor,而用于異步Action執行的AsyncControllerActionInvoker則創建ReflectedAsyncControllerDescriptor。ActionInvoker和ControllerDescriptor之間的關系可以通過如下圖所示的UML來表示。

      image

      對于ReflectedControllerDescriptor來說,包含其中的ActionDescriptor類型均為ReflectedActionDescriptor。而ReflectedAsyncControllerDescriptor描述的Controller可以同時包含同步和異步的Action方法,所以它可以包含任何類型的ActionDescriptor。

      具體來說,如果Action方法的返回類型為Task,對應的ActionDescriptor是一個TaskAsyncActionDescriptor對象如果Action方法名稱包含“Async”后綴,并且存在一個對應的以“Completed”后綴的方法,則對應的ActionDescriptor是一個ReflectedAsyncActionDescriptor對象;如果對應Completed方法不存在,對應的FindAction方法會直接拋出一個InvalidOperationException異常。在其它情況下的Action方法均是同步的,所以對應的ActionDescriptor類型為ReflectedActionDescriptor。ControllerDescriptor與ActionDescriptor之間的關系如下圖所示的UML來表示。

      image

      三、實例演示:AsyncActionInvoker對ControllerDescriptor的創建

      為了讓讀者對ActionInvoker對ControllerDescriptor的解析機制具有一個深刻的理解,同時也作為對該機制的驗證,我們做一個簡單的實例演示。通過前面的介紹我們知道在默認的情況下Controller采用AsyncControllerActionInvoker進行Action方法的執行,這個例子就來演示一下它生成的ControllerDescriptor是個怎樣的對象。我們通過Visual Studio的ASP.NET MVC項目模板創建一個空Web應用,并創建一個默認的HomeController,然后對其進行如下的修改。

         1: public class HomeController : AsyncController
         2: {
         3:     public void Index()
         4:     {
         5:         MethodInfo method = typeof(AsyncControllerActionInvoker).GetMethod("GetControllerDescriptor", BindingFlags.Instance | BindingFlags.NonPublic);
         6:         ControllerDescriptor controllerDescriptor = (ControllerDescriptor)method.Invoke(this.ActionInvoker, new object[] { this.ControllerContext });
         7:         Response.Write(controllerDescriptor.GetType().FullName + "<br/>");
         8:         CheckAction(controllerDescriptor, "Foo");
         9:         CheckAction(controllerDescriptor, "Bar");
        10:         CheckAction(controllerDescriptor, "Baz");
        11:  
        12:     }
        13:     private void CheckAction(ControllerDescriptor controllerDescriptor, string actionName)
        14:     {
        15:         ActionDescriptor actionDescriptor = controllerDescriptor.FindAction(this.ControllerContext, actionName);
        16:         Response.Write(string.Format("{0}:{1}<br/>",actionName, actionDescriptor.GetType().FullName));
        17:     }
        18:  
        19:     public void Foo() { }
        20:     public void BarAsync() { }
        21:     public void BarCompleted() { }
        22:     public Task Baz()
        23:     {
        24:         return new Task(DoNothing);
        25:     }
        26:     public void DoNothing() { }
        27: }

      我們首先將HomeController的基類從Controller改為AsyncController,并定義了Foo、BarAsync/BarCompleted和Baz四個方法,我們知道它們對應著Foo、Bar和Baz三個Action,其中Foo是同步Action,Bar和Baz分別是兩種不同定義形式(XxxAsync/XxxCompleted和Task)的異步Action。

      CheckAction用于根據指定的Action名稱從ControllerDescriptor對象中獲取用于表示對應Action的ActionDescriptor對象,最終將類型名稱呈現出來。在Index方法中,我們通過反射的方式調用當前ActionInvoker(一個AsyncControllerActionInvoker對象)的受保護方法GetControllerDescriptor或者用于描述當前Controller(HomeController)的ControllerDescriptor的對象,并將類型名稱呈現出來。最后通過調用CheckAction方法將包含在創建的ControllerDescriptor對象的三個ActionDescriptor類型呈現出來。

      當我們運行該程序的時候,在瀏覽器中會產生如下的輸出結果,從中可以看出ControllerDescriptor類型為ReflectedAsyncControllerDescriptor。同步方法Foo對象的ActionDescriptor是一個ReflectedActionDescriptor對象;以XxxAsync/XxxCompleted形式定義的異步方法Bar對應的ActionDescriptor是一個ReflectedAsyncActionDescriptor對象;而返回類型為Task的方法Baz對應的ActionDescriptor類型則是TaskAsyncActionDescriptor。

         1: System.Web.Mvc.Async.ReflectedAsyncControllerDescriptor
         2: Foo:System.Web.Mvc.ReflectedActionDescriptor
         3: Bar:System.Web.Mvc.Async.ReflectedAsyncActionDescriptor
         4: Baz:System.Web.Mvc.Async.TaskAsyncActionDescriptor

       

      ASP.NET MVC三個重要的描述對象:ControllerDescriptor
      ASP.NET MVC三個重要的描述對象:ActionDescriptor
      ASP.NET MVC三個重要的描述對象:ControllerDescriptor與ActionDescriptor的創建機制
      ASP.NET MVC三個重要的描述對象:ParameterDescriptor

      posted @ 2012-05-11 08:52  Artech  閱讀(6535)  評論(15)    收藏  舉報
      主站蜘蛛池模板: 亚洲国模精品一区二区| 国产AV永久无码青青草原| 久久无码中文字幕免费影院蜜桃| 中文字幕久久国产精品| 国产精品毛片一区二区| 玩弄漂亮少妇高潮白浆| 亚洲码国产精品高潮在线| FC2免费人成在线视频| 成人亚洲综合av天堂| 国产一区二区三区四区五区加勒比| 久久国产自拍一区二区三区| 91亚洲免费视频| 少妇被黑人到高潮喷出白浆| 无码伊人久久大杳蕉中文无码| 国产精品自在拍首页视频8| 精品人妻一区二区三区四区在线| 国产欧美日韩视频一区二区三区| 丰满人妻熟妇乱精品视频| 亚洲高清WWW色好看美女| 日韩av裸体在线播放| 91精品国产自产91精品| 少妇被粗大的猛烈进出69影院一 | 亚洲男人天堂2018| 亚洲国产精品高清久久久| 久99久热免费视频播放| 久久久久久免费一区二区三区| av中文字幕国产精品| 久久99精品久久久久麻豆| 亚洲国产精品嫩草影院久久| 中文字幕国产精品av| 粉嫩一区二区三区国产精品 | 国产二区三区不卡免费| 日区中文字幕一区二区| 你懂的在线视频一区二区| 全球成人中文在线| 欧美成人午夜在线观看视频| 国产强奷在线播放免费| 亚洲VA久久久噜噜噜久久无码| 99精品国产中文字幕| 亚洲区日韩精品中文字幕| 精品中文字幕一区在线|