S2AOP.NET を使用するにはS2Container の設定ファイル(diconファイル)で行います。 設定ファイルの配置場所は、とくに指定がありませんが、 通常「Crosscutting Concern」と同じ場所に配置するか、設定を行うコンポーネントと同じ場所に配置します。
アスペクトをコンポーネントに組み込みます。 Interceptorの指定は、ボディでJScript.NET式を使うか、子タグでcomponentタグを使います。
aspectタグで指定されたコンポーネントは、コンテナの初期化時にコンテナから取得されます。 そのため、aspectタグで指定されたコンポーネントのinstance属性がprototypeだったとしても、 Interceptor のメソッドが呼び出される度に新しいインスタンスが作成されるわけではありません。
カンマ区切りで対象となるメソッド名を指定することができます。 pointcutを指定しない場合は、コンポーネントが実装しているインターフェースのすべてのメソッドが対象になります。 メソッド名には正規表現(System.Text.RegularExpressions.Regex)も使えます。
pointcut 属性を指定してSystem.Collections.HashtableのAddメソッドとClearメソッドを対象とする場合以下のようになります。 pointcut属性を指定しない場合はSystem.Collections.Hashtableが実装しているインターフェース (ここではSystem.Collections.IDictionary)のメソッドが対象になります。
<component class="System.Collections.Hashtable"> <aspect pointcut="Add,Clear"> <component class="Seasar.Framework.Aop.Interceptors.TraceInterceptor"/> </aspect> </component>
正規表現を使ってSystem.Collections.Hashtableが実装しているインターフェース (ここではSystem.Collections.IDictionary)のメソッドすべてを対象としたい場合は、以下のように設定します。
<component class="System.Collections.Hashtable"> <aspect pointcut=".*"> <component class="Seasar.Framework.Aop.Interceptors.TraceInterceptor"/> </aspect> </component>
S2AOP.NETでは、以下のInterceptorを用意しています。また独自のInterceptorを簡単に作成できるようになっています。
Seasar.Framework.Aop.Interceptors.TraceInterceptor
トレース処理を「Crosscutting Concern」として扱うためのInterceptorです。 HashtableクラスにTraceInterceptorを適用したdiconファイルは、以下のようになります。対象とするメソッドはAddとします。
<component class="System.Collections.Hashtable"> <aspect pointcut="Add"> <component class="Seasar.Framework.Aop.Interceptors.TraceInterceptor"/> </aspect> </component>
詳しい使用方法はExamplesのTraceInterceptorを参照してください。
Seasar.Framework.Aop.Interceptors.MockInterceptor
Mockを使ったテストを簡単に行うためのInterceptorです。
独自にInterceptorを作成する場合は、次のインターフェースまたは、抽象クラスを実装します。
Seasar.Framework.Aop.IMethodInterceptor (インターフェース)
Seasar.Framework.Aop.Interceptors.AbstractInterceptor (抽象クラス)
インターフェースを実装する場合は、以下のInvokeメソッドを実装します。
public object Invoke(IMethodInvocation invocation)
抽象クラスを継承する場合は、以下のInvokeメソッドをオーバーライドします。
public override object Invoke(IMethodInvocation invocation)
AbstractInterceptor は、IMethodInterceptorを実装した抽象クラスです。 AbstractInterceptorには、Proxyオブジェクトを取得するCreateProxyメソッドとアスペクトを適用するコンポーネント定義を取得するGetComponentDefメソッドがあります。 アスペクトを適用したクラス名を必要とするInterceptor(例えば、ログ出力を行うInterceptor)を作成する場合は、 AbstractInterceptorを使用することで簡単にクラス名を取得することができます。
public object CreateProxy(Type proxyType)
protected IComponentDef GetComponentDef(IMethodInvocation invocation)
IMethodInvocation のプロパティTarget、Method、Argumentsで対象となるオブジェクト、メソッド、引数を取得できます。 proceed()を呼び出すと実際のメソッドが呼び出され実行結果を取得することができます。 以下のような独自のInterceptorを作成したとします。
C#
public class TestInterceptor : IMethodInterceptor { public object Invoke(IMethodInvocation invocation) { Console.WriteLine("Before"); // 呼ぶ前はBefore object ret = invocation.Proceed(); Console.WriteLine("After"); // 呼んだ後はAfter return ret; } }
IMethodInvocation#Proceed()を呼ぶ前と後で2分され、呼ぶ前は Beforeの個所を実行し、呼んだ後はAfterの個所を実行します。 1つのコンポーネントに複数のアスペクトが定義されている場合は、以下のよう実行されます。
詳しい使用方法はExamplesの独自実装によるInterceptorを参照してください。
diconファイルの設定を行わずプログラム上でアスペクトを組み込むこともできます。作成方法は次のようになります。
System.Collections.HashtableクラスにTraceInterceptorをプログラム上で適用する場合は、 次のようになります。 対象となるメソッドはgetTime()とします。
C#
IPointcut pointcut = new PointcutImpl(new string[]{"Add"}); IAspect aspect = new AspectImpl(new TraceInterceptor(), pointcut); AopProxy aopProxy = new AopProxy(typeof(IDictionary), new IAspect[]{aspect}, null, new Hashtable()); IDictionary proxy = (IDictionary) aopProxy.Create(); proxy.Add("aaa", "bbb");