はじめてのPostSharp

NEWSで取り上げたPostSharpが面白そうなので早速実験です。
まず、コンソールアプリケーションプロジェクトを作成して、MyTestAttributeクラスを作成します。

using System;
using PostSharp.Laos;

[Serializable]
class MyTestAttribute : OnMethodBoundaryAspect
{
    public override void OnEntry (MethodExecutionEventArgs eventArgs)
    {
        Console.WriteLine ("Enter:" + eventArgs.Method.Name);
    }

    public override void OnExit (MethodExecutionEventArgs eventArgs)
    {
        Console.WriteLine ("Exit:" + eventArgs.Method.Name);
    }
} 

OnMethodBoundaryAspectから継承するとメソッド呼び出しに割り込めるカスタム属性が作れるようです。あと、Serializable属性をつける必要があります。次は・・・

・・・

なんと、これで完成です!

早速、テストしてみましょう。

using System;

[MyTest]
class Program
{
    static void Main (string[] args)
    {
        string msg = "Taro";
        SayHello (msg);
        SayGoodby (msg);
    }

    static void SayHello (string msg)
    {
        Console.WriteLine ("Hello, {0}",msg);
    }

    static void SayGoodby (string msg)
    {
        Console.WriteLine ("Goodby {0}",msg);
    }
} 

/* 結果
Enter:Main
Enter:SayHello
Hello, Taro
Exit:SayHello
Enter:SayGoodby
Goodby Taro
Exit:SayGoodby
Exit:Main
 */

ごく普通のコンソールアプリにMyTest属性をつけただけですが、ちゃんと割り込みされています。凄い。

でも、アスペクトの縫いこみなんてやってやった覚えはありません。はてはて?

もちろん、手品には種も仕掛けもあって、ビルドの最後に自動的にアスペクトが縫いこまれているのです。犯人はMSBuildMSBuildディレクトリを見ると、

C:\Program Files\MSBuild\v2.0\Custom.After.Microsoft.Common.targets

というファイルが見つかります。ファイル名のAfterから分かるように、ビルド後にここに指定されたカスタムビルドが実行されるのでした。で、PostSharpのカスタムビルドは参照アセンブリにPostSharp.Publid.dllが含まれるかどうかを判断して、アスペクトの埋め込みを行っていたのでした。