これは、 MVCフレームワークの内部構造に関する一連の記事の3番目の記事です。 前の部分の要約: MVCフレームワークにアップグレードする必要がありますか? ; MVCフレームワークの操作メカニズム: パート1およびパート2 。 この記事では、MVCフレームワークの重要な部分であるコントローラーファクトリーのメカニズムに焦点を当て、フレームワーク全体が機能するようになります。
なぜ「工場」なのか?
ファクトリーは、クラス自体を指定せずにオブジェクト(クラスのインスタンス)を作成するメカニズムを定義するデザインパターンの名前です。 詳細については、 Wikiを参照してください。 MVCフレームワークでは、名前が示すとおり、コントローラーファクトリはコントローラーオブジェクトを作成するように設計されています。 必要なコントローラーに関する情報は、クラス名を持つ文字列の形式でASP.NETルーティングメカニズムから取得されるため、コントローラーファクトリはこの文字列に基づいてコントローラーオブジェクトを構築します。
コントローラー工場
通常、ファクトリーは、インターフェースによって定義されたクラスのオブジェクトを作成します。 MVCフレームワークコントローラーファクトリの場合、このインターフェイスはIControllerです。 一般的に、コントローラーファクトリインターフェイスの定義は次のようになります。
public interface IControllerFactory {
IController CreateController(RequestContext requestContext, string controllerName);
void ReleaseController(IController controller);
}
* This source code was highlighted with Source Code Highlighter .
非常にシンプルなインターフェイス: CreateControllerメソッドはIControllerを実装するオブジェクトを返し、 ReleaseControllerはコントローラーが存在しなくなったときにコントローラーを削除する必要があります。
コントローラファクトリが必要なコントローラインスタンスを返すために、パラメータはコントローラの名前controllerNameおよびrequestContextリクエストコンテキストの形式で渡され、ASP.NETルーティングメカニズムを形成します。 フレームワークにはファクトリのデフォルト実装が含まれているため、ASP.NET MVCフレームワーク開発者は、コントローラファクトリの独自の実装を記述する必要はありません。 この実装はDefaultControllerFactoryクラスです。
DefaultControllerFactory
ASP.NET MVCフレームワークエンジンがユーザー要求を受信すると、関連するMvcRouteHandlerハンドラーがそれを処理します。 適切なルートが見つかったら、MvcRouteHandlerはそのルートに関連付けられたハンドラーを呼び出します。 デフォルトでは、これはコントローラーファクトリーを作成して使用するMvcHandlerです。
コントローラーファクトリクラスを取得するために、MvcHandlerはControllerBuilderクラス( singletonとして実装)を使用します。このクラスには、コントローラーファクトリのインスタンスを持つフィールドが常に含まれています。 デフォルトでは、ControllerBuilderにはDefaultControllerFactoryクラスのインスタンスが含まれており、それを返します。 ただし、開発者はglobal.asaxの簡単なコードでコントローラーファクトリを定義できます。
protected void Application_Start()
{
RegisterRoutes(RouteTable.Routes);
ControllerBuilder.Current.SetControllerFactory( new ControllerFactory());
}
* This source code was highlighted with Source Code Highlighter .
ここで、 ControllerFactoryはコントローラーファクトリのカスタムクラスです。
そのため、標準またはユーザー定義のコントローラーファクトリが作成されます。 その後、 CreateControllerメソッドが呼び出されます。このメソッドには、コントローラークラスの名前と、ルーティングメカニズムによって形成された要求コンテキストが渡されます。 これらのパラメーターのデータベースに基づいて、ファクトリーはコントローラークラスのインスタンスを返すか、例外を発生させる必要があります。
標準コントローラファクトリを使用する場合、特にリクエストのコンテキストで、RequestContext.RouteData.DataTokensルートパラメータのセットを転送できます。これには、コントローラクラスを検索するためのネームスペース名(Namespacesパラメータの値を含む)を含めることができます。 プロジェクトに多くのネームスペースがあり、コントローラーが1つだけに制限されている場合、これは便利で、アプリケーションを高速化できます。 詳細については、ルート作成の説明を参照してください。
コントローラーファクトリを定義する理由と方法
実際、コントローラーファクトリーのオーバーライドは、MVC Frameworkプロジェクトを作成するための完全にオプションの手順です。 ただし、コントローラークラスの作成を制御するツールは、開発者にとって有用な場合があります。
コントローラーファクトリの最も一般的な使用例は、 UnityなどのIoC / DIコンテナーを実装して、コンテナーを通じてコントローラークラスをインスタンス化することです。 IoC / DIコンテナーの必要性と必要性は他の記事のトピックですが、そのようなコンテナーをプロジェクトで使用する場合、コントローラーファクトリを再定義することは、コンテナーを介してコントローラーを作成する良い方法です。 この実装の説明はこの記事にあります。ここでは、Unityを使用して作成されたカスタムコントローラーファクトリのクラスのみを示します。
public class UnityControllerFactory : DefaultControllerFactory
{
IUnityContainer _container;
public UnityControllerFactory(IUnityContainer container)
{
_container = container;
}
protected override IController GetControllerInstance(Type controllerType)
{
if (controllerType == null )
throw new ArgumentNullException( "controllerType" );
if (! typeof (IController).IsAssignableFrom(controllerType))
throw new ArgumentException( string .Format(
"Type requested is not a controller: {0}" , controllerType.Name),
"controllerType" );
return _container.Resolve(controllerType) as IController;
}
}
* This source code was highlighted with Source Code Highlighter .
ご覧のとおり、新しいコントローラーファクトリーはDefaultControllerFactoryを継承し、タイプによってコントローラークラスをインスタンス化するためにDefaultControllerFactoryによって使用されるGetControllerInstanceメソッドをオーバーロードします。
コントローラーファクトリを使用する別のオプションとして、コントローラーのブラックリストとホワイトリストの導入があります。これは、クライアント要求を通じて呼び出すことができるか、できない場合があります。 これは、しばらく使用停止できる大量のコントローラーを含む大規模プロジェクトを作成する場合に意味があります。 ブラックリストとホワイトリストをチェックするコントローラーのファクトリーを実装すると、作成段階でもコントローラーを使用から削除する問題を簡単に解決できます。 さらに、このためにコードを編集したり、新しいルートを作成したり、アセンブリを再コンパイルしたり、アプリケーションを再起動したりする必要はありません。 「ブラック」または「ホワイト」リストを編集するだけで十分です。これらのリストは、xmlファイルでも表現できます。
ポイント
コントローラーファクトリがどのように機能するかを調べました。 以下を学ぶことが重要です。
- コントローラーファクトリはルーティングメカニズムから呼び出されます。
- コントローラーファクトリは、コントローラークラスをインスタンス化します。
- コントローラのファクトリは再定義できますが、絶対に必要というわけではありません。
- MVCフレームワークメカニズムの動作を中断させないために、コントローラーファクトリインスタンスを基本クラスDefaultControllerFactoryから継承することをお勧めします。
- IoC / DIコンテナーを使用する場合、コントローラーファクトリーが大いに役立ちます。