アーカイブ

Archive for 2008年4月

ASP.NET MVC の仕組み

2008年4月11日 コメントを残す

ASP.NET MVC Preview 2 はソースコードが公開されています。

参考:ASP.NET MVC のソースコードが利用可能に – ScottGuさんのブログ翻訳

このソースコードを参考に、ASP.NET MVC がどのような仕組みで実現されているかを調べてみました。
まずはリクエストを受けるところから。

  • UrlRoutingModuleがリクエストを受け取る
  • Global.asax.csでRouteの初期化を行うときに設定するMvcRouteHandlerを通して、MvcHandlerが処理を行う対象として設定される

これがまず最初の段階です。
ASP.NET MVC のサンプルプログラムのweb.configを見ると、UrlRoutingModuleが追加されています。
Moduleはすべてのリクエストを受け取りますので、ここでリクエストを処理するHandlerを新たに設定することで、すべてのリクエストをMvcHandlerが処理するようになります。。
残念ながら System.Web.Routing.dll のソースコードは公開されていませんので、その内部での処理は直接見ることはできませんが、まぁ、上記のようになっています。

MvcHandlerはIHttpHandlerを継承していますので、ashxファイルなどと同じようにProcessRequestメソッドが呼び出されることになります。
このあたりはASP.NETの仕組みそのものが利用されています。

さて、ここからは公開されているソースコードで処理を追いかけることができます。

  • MvcHandlerはfactoryパターンを利用してリクエストされているURLに対応するControlerクラスをインスタンス化する
  • Controlerはリフレクションを利用してリクエストされているURLに対応するActionメソッドを呼び出す

このようなかたちでControler内に実装しているActionメソッドが呼び出されます。
ここから先はActionメソッドの実装によって変わってきますが、最初は単純にViewを呼び出す場合をみてみましょう。
この場合はRenderViewメソッドにViewの名称を引数として渡します。

  • RenderViewメソッドは渡された引数をもとに、CreateInstanceFromVirtualPathを利用してPageクラスのインスタンスを生成する

Viewとして作成するaspxはViewPageを継承します。このViewPage自体がPageを継承していますから、ViewというのはViewDataを扱うために拡張されたPageクラスだと思えばいいようです。
このインスタンスに対しても、通常のPageと同じようにPage_Load等の各種イベントが発生します。

次にActionメソッドの中でリクエストされたデータを受け取り、データを更新するような場合はどうなるでしょう。

  • ViewDataにBindingHelperExtensionsクラスのUpdateFromメソッドを利用してデータを埋め込み、更新に必要な処理を行う
  • RedirectToActionメソッドで渡された引数のURLにResponse.Redirectを実行する

データの更新をサポートするためのUpdateFromメソッドはRequest.Formの内容をkeyの名前をもとに、ViewDataの同名のプロパティに埋め込みます。
このため、データ入力用に生成されるHTMLの入力領域には、IDとしてそのデータを埋め込むViewDataのプロパティの名前をつけておく必要があります。

また、RedirectToActionの実態はResponse.Redirectなので、ここでブラウザとの通信が発生し、それにおよってブラウザに表示されるURLがリダイレクト先のActionになります。
データを更新したあとにデータの一覧を表示する、といった場合にこのような動きをさせることになります。

ASP.NET MVC の仕組みの概要としてはこんなところでしょうか。
調べてみると、ASP.NET MVC ではweb.configへの記述の追加やbinフォルダへのdllの追加はありますが、それらはすべてASP.NETの拡張といったレベルであり、ASP.NETそのものに手を入れている部分はまったくなさそうです。
ASP.NETはもともと柔軟で拡張性を持ったフレームワークなのですが、ASP.NET MVC はその特徴を十分に活用したサンプルと考えることもできるようです。

カテゴリー:.NET, ASP.NET 備忘録