ASP.NET MVCコントローラアクティブ化(一)
4303 ワード
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の前の部分をざっと説明しますが、まず以下の図をご覧ください.
以上のように、ここではコントローラタイプのキャッシュ対象であるControllerType Cacheについて説明するが、ControllerType CacheはIControllerインタフェースを実現したすべての共通クラスをロードMVC-ControllerType Cacheにキャッシュする.xmlファイルにあります.もちろんこれらはすべてフレームワークがしているので、私たちは理解して、その中の思想を学ぶだけでいいです.
リクエストがデフォルトリクエストハンドラに到達すると、デフォルトのコントローラファクトリDefaultControllerFactoryがRouteDataのDataToken【NameSpaces】に定義されたネーミングスペースとValues【controller】のコントローラ名に基づいて判断し、具体的にどのように判断したかはControllerType Cacheオブジェクトによって照会されて一致する.
この名前に対応するコントローラがコントローラ名に基づいてキャッシュに存在するかどうかを問い合せ、存在する場合はILookupタイプオブジェクトに格納し、RouteDataのDataToken【NameSpaces】で定義されたネーミングスペースに基づいてILookupオブジェクトのコントローラタイプが存在するネーミングスペースと比較し、同じ場合は戻りセットにこのタイプを追加します.異なる場合は、RouteDataのDataToken【NameSpaces】の残りのネーミングスペース値を1つずつ比較し続けます.
返されるタイプのセットに応じて、合計が0の場合は空に戻り、合計が1の場合はこのセットのタイプを返し、1より大きい場合はCreateAmbiguousControllerExceptionタイプの例外が発生します.
この時点でDefaultControllerFactoryでコントローラタイプ(Type)が取得されました.
要約2.2で示す部分はIControllerActivatvatorインタフェースタイプの実装である. 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フレームでIControllerActivvatorインタフェースタイプを実現したデフォルト実装クラスDefaultControllerActivvatorタイプによってIControllerを作成するものであり、一方、DefaultControllerActivvatorでは、DependencyResolverタイプによってIDependencyResolverインタフェースのデフォルト実装クラスを作成することで実現されます.
IDependencyResolverインタフェースには、最終的にタイプを作成するために使用される方法であるGetService()メソッドがあり、カスタマイズして実装することもできます.これも拡張点の1つです.インタフェースタイプといえば、MVCにはIDependencyResolverインタフェースをデフォルトで実現するタイプのDefaultDependencyResolver、DefaultDependencyResolverタイプのGetService()メソッドのデフォルト実装方式Activatvatorがある.CreateInstance(serviceType);つまり、通常は反射によってタイプが作成されます.
HandlerからIcontrollerまでのプロセス図を見てみましょう.
上記および前編ではMVCのデフォルト実装方式であり、各部分をカスタマイズして拡張することができ、MvcHandler、DefaultControllerFactory、DefaultDependencyResolverなどのタイプがある.
コントローラのアクティブ化中に注入可能なすべての拡張点が後述します.
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 }
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);