いろんなセッションビデオやサンプルコードによく登場してる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でシャットダウンしない?)なので未確認!雰囲気が伝わればいいかな、なんて。