いろんなセッションビデオやサンプルコードによく登場してるWebActivator。属性指定のしかたから、.NET4で登場したPreApplicationStartMethod(AssemblyInfo.csに指定するやつ)に関する何かだろうと勝手に解釈して、ちゃんと見てなかったんだけど、なんか急に見てみたくなった。
解釈はおおむね間違ってないんだけど、PreAppricationStartMethodだと1個しか指定できない(よね?)のと、フックポイントが起動直後しかない(そりゃそうだ)のを拡張してしまおうというものでした。なるほど。
Pre/Post/Shutdowの3箇所に仕込めるんですね。
- PreApplicationStartMethod
- PostApplicationStartMethod
- ApplicationShutdownMethod
この3種類。うまいこと考えてますね。PreとPostはAOPっぽい感じです。タイミングはPreはそのままPreなんだけど、PostはMicrosoft.Web.Infrastructure.DynamicModuleHelper.DynamicModuleUtility.RegisterModule を使って動的にロードする初期化HttpModule(これ自体ちゃんとWebActivatorに含まれてるので気にすることは無いですね)のInitイベントで実行。ShutodownはそのHttpModuleのDispose時に実行。
David Ebbo: Register your HTTP modules at runtime without config
面白いですね。賢いですね~。アセンブリ属性にしてるのは使い勝手を考慮してのことでしょう。属性宣言とクラス実装が近くにあるはずだから、クラス属性にしてもいいような気もするけど、使い勝手は大事でしょう!
[assembly: WebActivator.PreApplicationStartMethod(typeof(クラス), "実行メソッド名")]
[assembly: WebActivator.PostApplicationStartMethod(typeof(クラス), "実行メソッド名")]
[assembly: WebActivator.ApplicationShutdownMethod(typeof(クラス), "実行メソッド名")]
こんな感じでアセンブリ内に宣言します。いくつ宣言してもいいです。ActivationManager(これが標準のPreApplicationStartMethodで指定されてるよ)が実行時にbinフォルダのアセンブリから全部抽出してくれます。
davidebbo / WebActivator / overview – Bitbucket
オレオレBootstrapperを卒業するときがきましたね!
注意点として、HttpModuleを利用するPostとShutdownはAppDomainがロードされなおすたびに実行されるので、何度も実行されるのでその辺気をつけましょう。
とにかくNuGetで Install-Package webactivator とタイプしてインストールしてみて以下のコードで動かしてみました。
[assembly: WebActivator.PreApplicationStartMethod(typeof(Bootstrapper1), "Pre")]
[assembly: WebActivator.PreApplicationStartMethod(typeof(Bootstrapper2), "Pre")]
[assembly: WebActivator.PreApplicationStartMethod(typeof(Bootstrapper3), "Pre")]
[assembly: WebActivator.PostApplicationStartMethod(typeof(Bootstrapper1), "Post")]
[assembly: WebActivator.PostApplicationStartMethod(typeof(Bootstrapper2), "Post")]
[assembly: WebActivator.PostApplicationStartMethod(typeof(Bootstrapper3), "Post")]
[assembly: WebActivator.ApplicationShutdownMethod(typeof(Bootstrapper1), "Shutdown")]
[assembly: WebActivator.ApplicationShutdownMethod(typeof(Bootstrapper2), "Shutdown")]
[assembly: WebActivator.ApplicationShutdownMethod(typeof(Bootstrapper3), "Shutdown")]
namespace Mvc3
{
public class Bootstrapper
{
public static void Pre(string name)
{
Console.WriteLine("Pre : "+name + " " + DateTime.Now);
}
public static void Post(string name)
{
Console.WriteLine("Post : " + name + " " + DateTime.Now);
}
public static void Shutdown(string name)
{
Console.WriteLine("Shutdown : " + name + " " + DateTime.Now);
}
}
public class Bootstrapper1
{
private static string Name = "1番";
public static void Pre()
{
Bootstrapper.Pre(Name);
}
public static void Post()
{
Bootstrapper.Post(Name);
}
public static void Shutdown()
{
Bootstrapper.Shutdown(Name);
}
}
public class Bootstrapper2
{
private static string Name = "2番";
public static void Pre()
{
Bootstrapper.Pre(Name);
}
public static void Post()
{
Bootstrapper.Post(Name);
}
public static void Shutdown()
{
Bootstrapper.Shutdown(Name);
}
}
public class Bootstrapper3
{
private static string Name = "3番";
public static void Pre()
{
Bootstrapper.Pre(Name);
}
public static void Post()
{
Bootstrapper.Post(Name);
}
public static void Shutdown()
{
Bootstrapper.Shutdown(Name);
}
}
}
VS2010SP1だとIIS Expressで実行ができるけど、あえて外部コマンドでIIS Expressを指定して実行してみます。
コンソールのスクリーンショットを取りたかったからデス!これって統合されたらどこで見ればいいんだろか。出力ウィンドウだとちょっと違うじゃん?ん~。まぁ、いいか。おいおい分かるでしょう。
残念ながらShutdownは表示するまで待つのも設定変えるのも面倒(IIS ExpressだとidleTimeoueでシャットダウンしない?)なので未確認!雰囲気が伝わればいいかな、なんて。