AspectDNG を使ってインターフェースを追加実装する

.NET 用の AOP ツールである AspectDNG を使って、指定のクラスにインターフェースを追加実装する。

手順は以下の通り

  1. クラスとインターフェースの作成
  2. アスペクトの定義と適用
  3. テストクラスの作成と実行

クラスとインターフェースの作成

アスペクトの適用対象とするクラスとアスペクトで追加するためのインターフェースを作成する

public class Data {}
public interface IChecker
{
    void Check(int num, string msg);
}

これをビルドしてアセンブリを作成しておく

>csc /t:library /out:commonlib.dll Data.cs IChecker.cs

アスペクトの定義と適用

AspectDNG ではカスタムアトリビュートでアスペクトが定義でき、インターフェースを追加実装するには以下のカスタムアトリビュートを使用する事になる。

  • ImplementInterface でインターフェースを追加
  • Insert でメソッドの実装を追加
using System;
using DotNetGuru.AspectDNG.Joinpoints;

//Data クラスへインターフェースを追加する定義
[ImplementInterface("Data")]
public interface ICheckerAspect : IChecker
{
}

//アスペクトの定義クラス。
//Check メソッドのシグネチャが同じだけでは
//ウィーブ後にインターフェースの実装として認識されないようなので
//IChecker インターフェースを実装するようにしている
public class SimpleAspect : IChecker
{
    //Data クラスへ Check メソッドの実装を追加する定義
    [Insert("Data")]
    public void Check(int num, string msg)
    {
        Console.WriteLine("--- Check : {0}", this);
    }
}

ここで、SimpleAspect クラスの IChecker インターフェース実装宣言を外すと、実行時に System.TypeLoadException('Data' にあるメソッド 'Check' に実装が含まれていません)が発生するため注意が必要。

アスペクト定義クラスをビルドして、事前に作成しておいたアセンブリにアスペクトをウィーブする。

>csc /t:library /out:aspects.dll /r:aspectdng.exe;commonlib.dll SimpleAspect.cs
>aspectdng.exe commonlib.dll aspects.dll

aspectdng.exe の実行で commonlib.dll がアスペクト適用後のアセンブリで置換される。

テストクラスの作成と実行

Data クラスへ IChecker インターフェースの実装が追加されている事を確認するためのテストクラス作成

public class Tester
{
    public static void Main(string[] args)
    {
        //Data クラスへ IChecker インターフェースの実装が
        //追加されている事を確認
        IChecker checker = new Data() as IChecker;
        checker.Check(100, "test");
    }
}

実行結果は以下のようになり、インターフェースの実装が追加されている事が確認できる。

>csc /r:commonlib.dll;aspects.dll Tester.cs
>Tester.exe
--- Check : Data?