asp.NetController学習一

8406 ワード

1.controllerクラス
Controllerの実行はそのExcuteメソッドの呼び出しに現れ,IControllerというインタフェースでは1つのExcuteメソッドしか定義されておらず,このメソッドは同期的に実行される.
public interface IController{ void Excute(RequestContext RequestContext);}

非同期方式のため、System.Web.Mvc.Asyncネーミングスペースには、次のコードに示すようにIAsyncControllerのインタフェースが定義されています.
        public interface IAsyncController : IController
        {
            IAsyncResult BeginExecute(RequestContext requestContext, AsyncCallback callback, object state);
            void EndExecute(IAsyncResult asyncResult);
        }

IAsyncControllerインタフェースはIControllerインタフェースから派生し、ControllerはBeginExcuteとEndExecuteメソッドを前後して呼び出すことによって非同期で実行する.もう1つの非常に重要なベースクラスControllerBaseは、デフォルトではすべてのControllerクラスが継承し、抽象クラスであり、ControllerBaseもIControllerインタフェースを実現しています.このクラスに表示されるインタフェースを実装したExcuteメソッドは、保護されたダミーメソッドExcuteを呼び出し、後者は抽象メソッドExcuteCoreメソッドを呼び出し続け、ControllerBaseの継承者として、ExcuteCoreメソッドによってControllerの実行を完了する必要があります.以下はControllerBaseのコードクリップです
        public abstract class ControllerBase : IController
        {
            public ViewDataDictionary ViewData { get; set; }
            public dynamic ViewBag { get; }
            public TempDataDictionary TempData { get; set; }
protected virtual void Execute(RequestContext requestContext); protected abstract void ExecuteCore(); protected virtual void Initialize(RequestContext requestContext); void IController.Execute(RequestContext requestContext); }

ターゲットControllerは、実行後に応答としてViewを返します.この場合、ControllerはTempData、ViewBag、ViewDataからViewに値を転送できます.定義からTempDataとViewDataはいずれも辞書構造のデータコンテナを返すことがわかりますが、両者の違いはTempDataの名前の通り、格納されているデータは一時的で、一度使った後では使えません.ViewDataは複数回使用できます.ViewBagは動的オブジェクトを格納することができ、つまり任意の属性を指定することができ、属性名はデータ辞書のKeyである.また、ControllerContextというクラスもあり、このクラスのオブジェクトはRequestContextとControllerオブジェクトのカプセル化と見なすことができます.上記のControllerBaseクラスの定義から、RequestContextのパラメータを持つInitializeメソッドがあり、このメソッドが実行されるとControllerContextオブジェクトが作成されます.保護されたダミーメソッドExcuteは、ExcuteCoreメソッドを実行する前にInitializeメソッドを実行します.我々はVSによって作成されたコントローラが実際に抽象的なControllerクラスから継承されており,VSではControllerがController Baseクラスを継承し,IControllerインタフェースとIAsyncControllerインタフェースを実現するほか,5種類のフィルタのインタフェースを実現していることがわかる.これに加えて、IDisposableインタフェースなどの他のインタフェースも実装されており、MVCのControllerアクティブ化システムは、Controller実行が終了すると、Disposeメソッドを呼び出して対応するリソース回収作業を完了します.
2.同非同期、ControllerFactory、ControllerBuilder
抽象クラスControllerの定義からIAsyncControllインタフェースが実装されていることが分かるが、このインタフェースはインタフェースIControllerインタフェースから継承されているため、Controllerは同期方式(Excute)も非同期方式(BeginExcute/EndExcute方式)も実装できる.ControllerクラスにはDisableAsyncSupportプロパティがあります.デフォルトはfalseです.trueに設定すると、同期でのみ実行され、falseの場合は非同期で実行されます.
   ASP.NET MVCは、Controllerのアクティブ化に対応するファクトリ、すなわちControllerFactoryクラスを定義し、すべてのControllerFactoryクラスは、次のコードフラグメントのようなIControllerFactoryインタフェースを実現する
        public interface IControllerFactory
        {
            IController CreateController (RequestContext requestContext,string controllerName);
            SessionStateBehavior GetControllerSessionBehavior(RequestContext requestContext, string controllerName);
            void ReleaseController(IController controller);
        }

ControllerFactoryは、Controllerオブジェクトの作成と解放を担当します.作成はCreateControllerというメソッドに反映され、解放はReleaseControllerメソッドに反映されます.もう1つのGetControllerSessionBehaviorメソッドは、SessionStateControllerのタイプの列挙値を返します.4つの属性は、デフォルトのASPを使用することを示すDefaultです.NETロジックは、要求されたセッション状態の動作を決定する.Requeiredは、リクエストに対して完全な読み取り/書き込みセッションステータス動作を有効にします.ReadOnly:リクエストの読み取り専用セッションステータス動作を有効にします.Disabledはセッションステータスを無効にします.具体的にどのような挙動をとるかはhttpコンテキスト,HttpContextの静的属性Currentに依存する.
Controllerオブジェクトをアクティブ化するためのControllerFactoryは、最終的にはControllerBuilderを介してASPに登録される.NET MVCフレームの中の.
    public class ControllerBuilder
    {
        public ControllerBuilder();
        public static ControllerBuilder Current { get; }
        public HashSet<string> DefaultNamespaces { get; }

        public IControllerFactory GetControllerFactory();
        public void SetControllerFactory(IControllerFactory controllerFactory);
        public void SetControllerFactory(Type controllerFactoryType);
    }

ControllerBuilderのCurrentは現在使用されているオブジェクトを返し、2つのリロードされたSetControllerFactoryメソッドはControllerFactoryの登録を実現します.異なるのは、最初に登録されたのは特定のControllerFactoryオブジェクトで、2番目に登録されたのはControllerFactoryのタイプです.2つ目の方法で登録する場合、GetControllerFactoryは、実行時にActivatvatorの静的メソッドCreateInstanceを呼び出すことによってオブジェクトを作成します.つまり、この場合、GetControllerFactoryメソッドを呼び出すたびにオブジェクトのインスタンス化が常に伴いますが、MVCメカニズムではインスタンスのオブジェクトはキャッシュされません.したがって、第1の方法を採用すると、GetControllerFactoryから直接特定のオブジェクトが返されるようになります.
ルーティングシステムが要求を解析するとRouteDataオブジェクトが生成されることを知っています.Valuesプロパティにはターゲットコントローラの名前が保存されています.ネーミングスペースを指定しない場合、同じ名前のコントローラ名がある場合は、例外が報告されます.Controllerアクティベーションシステムでは、ルーティングの登録時に指定されたネーミングスペースの優先度を向上させる方法として、RouteオブジェクトのDataTokensプロパティで表されるRouteValueDictionaryオブジェクトにネーミングスペースリストが保存されます(この場所ではバックアップネーミングスペースも指定できます).もう1つの方法は、ControllerBuilderでDefaultNamespacesプロパティ、ControllerBuilderを指定することです.Current.DefaultNamespaces.Add(「ネーミングスペース」)です.しかし、前者は優先度が高い.
3.controllerのアクティブ化とルーティング
ルーティングシステムは、要求がIISによってASPに配信するものと見なすことができる.NETパイピング後の最初のバリアは,次にControllerのアクティブ化システムとルーティングシステムがどのように有機的に結合されているかを学習する.前の知識から私たちはASP全体を知っています.NETのルーティングシステムは、現在のリクエストに対してHttpHandlerを動的にマッピングするUrlRoutingModuleというHttpModuleの上に構築されています.すなわち、グローバルルーティングテーブルを介して要求に対してルーティング解析を実施し、RouteDataオブジェクトを生成し、このオブジェクトのRouteHandlerを用いて、現在の要求に最終的にマッピングされるHttpHandlerを得る.RouteHandlerオブジェクトはMVCメカニズムでMvcRouteHandlerオブジェクトです.では、最も簡単な本質を見ることができます.それは、RouteDataのMvcRouteHandlerオブジェクトがHttpHandlerオブジェクトを創造したことです.MvcRouteHandlerを見てみましょう
    public class MvcRouteHandler : IRouteHandler
    {
        public MvcRouteHandler();
        public MvcRouteHandler(IControllerFactory controllerFactory);

        protected virtual IHttpHandler GetHttpHandler(RequestContext requestContext);
        protected virtual SessionStateBehavior GetSessionStateBehavior(RequestContext requestContext);
    }

MvcRouteHandlerでは、コンストラクション関数で指定されたControllerFactoryオブジェクトが維持されており、指定されていなければ現在のControllerBuilderオブジェクトのGetControllerFactoryメソッドが呼び出されます.HttpHandlerオブジェクトの取得に加えて、MvcRouteHandlerは、RequestContextのRouteDataオブジェクトからターゲットControllerの名前を取得する現在のhttpのセッション状態を設定します.この名前とRequestContextオブジェクトは、パラメータとしてControllerFactoryを呼び出すGetControllerSessionBehaviorメソッドで、SessionStateBehaviorのタイプの列挙を取得し、最後にセッション状態を設定します.RouteDataのRouteHandlerプロパティは、最初は対応するルーティングオブジェクトに由来し、RouteCollectionの拡張メソッドMapRouteを呼び出して登録されたRouteオブジェクトに対して、対応するRouteHandlerはMvcRouteHandlerオブジェクトであり、このオブジェクトの作成時に指定されたControllerFactoryが表示されないため、したがって、現在のControllerBuilderオブジェクトのGetControllerFactoryメソッドを呼び出すことで得られるControllerFactoryはデフォルトで使用されます.
GetHttpHandlerメソッドでは最後にretutn new MvcHandler(requestContext);ControllerBuilderのGetControllerFactoryメソッドを使用したControllerFactoryは、MvcRouteHandlerによってセッション状態モードを取得するために使用されるだけで、MvcHandlerだけがターゲットControllerオブジェクトを実際に作成します.MvcHandlerは、IHttpHandlerインタフェースとIHttpAsyncHandlerインタフェースを同時に実装するため、常に非同期で実行され、最終的にControllerをアクティブにする作業は、現在のControllerBuilderによって提供されているControllerFactoryオブジェクトによってターゲットControllerオブジェクトをアクティブにします.最後にMvcHandlerはリリースクリーンアップを実施します.