はじめに
以前書いた Policy Injection Application Block のサンプルは構成ファイルでインターセプトするメソッドを指定していました。インターセプトするメソッドは属性でも指定可能なので、今回はその方法を試してみました。
カスタム CallHandler を作成
[ConfigurationElementType(typeof(CustomCallHandlerData))] public class EventLogCallHandler : ICallHandler { public int Order { get; set; } public EventLogCallHandler(NameValueCollection attributes) { // このコンストラクタは必須みたい } private const string SOURCE = "PIABSample"; public IMethodReturn Invoke(IMethodInvocation input, GetNextHandlerDelegate getNext) { // メソッド呼び出し前にログを出力 EventLog.WriteEntry(SOURCE, string.Format("{0} メソッドを呼び出します。", input.MethodBase.Name), EventLogEntryType.Information); // メソッド呼び出し IMethodReturn result = getNext()(input, getNext); // メソッド呼び出し後にログを出力 if (result.Exception != null) { // 例外が発生したとき EventLog.WriteEntry(SOURCE, string.Format("{0} メソッド呼び出しで例外が発生しました。", input.MethodBase.Name), EventLogEntryType.Error); } else { EventLog.WriteEntry(SOURCE, string.Format("{0} メソッドを呼び出しました。", input.MethodBase.Name), EventLogEntryType.Information); } return result; } }
前に作成したものをそのまま流用。
カスタム HandlerAttribute を作成
public class Wankuma : MarshalByRefObject { // 作成した属性を付与 [EventLogCallHandler] public void Cry() { Console.WriteLine("クマ〜"); } }
作成した EventLogCallHandlerAttribute をCry メソッドに付与しています。構成ファイルでメソッドを指定する必要はありません。
これで PolicyInjection.Create メソッドで生成した Wankuma インスタンスの、 Cry メソッドが呼び出される前と後にイベントログが出力されます。
まとめ
インターセプトするメソッドの指定は、構成ファイルを記述するよりも、属性を使った方が遥かに楽ですね。ちなみに、PIAB には既にロギングや検証など数種類の CallHandler と HandlerAttribute が用意されています。今回のサンプルで取り上げたロギングは、自作せずに用意されているクラスを使うのも良いでしょう。