Microsoft Enterprise Library の一部として Unity (v2.0) を使用しているアプリケーションを使用しています。メソッドの先頭に属性を追加できるように設定されており、メソッドが実行される前に何らかの処理 (トレース/ロギング/キャッシュなど) が行われます。以下のサンプルコード:
static void Main(string[] args)
{
IUnityContainer myContainer = new UnityContainer()
.AddNewExtension<Interception>()
.RegisterType<IFoo, Foo>(
new Interceptor<InterfaceInterceptor>(),
new InterceptionBehavior<PolicyInjectionBehavior>()
);
IFoo myFoo = myContainer.Resolve<IFoo>();
myFoo.fooMethodCall();
}
public class TraceAttribute : HandlerAttribute
{
public override ICallHandler CreateHandler(IUnityContainer container)
{
return new TraceCallHandler();
}
}
public class TraceCallHandler : ICallHandler
{
public int Order { get; set; }
public IMethodReturn Invoke(IMethodInvocation input, GetNextHandlerDelegate getNext)
{
IMethodReturn methodReturn;
//Do tracing/chaching/other funky stuff
methodReturn = getNext()(input, getNext);
return methodReturn;
}
}
public interface IFoo
{
int fooMethodCall();
}
public class Foo : IFoo
{
[Trace]
public int fooMethodCall()
{
return 0;
}
}
さて、これが機能する方法に関して私が抱えている 2 つの厄介な問題と、1 つのかなり深刻な問題があります。最初の煩わしさは、生成されるスタック トレースのサイズです。5 レベルの深さの関数をデバッグしようとすると、ナビゲートするのが非常に難しい厄介なスタック トレースが発生します。
2 番目の煩わしさは、VS2010 を使用してデバッグする場合、ステップインできないように見えることfooMethodCall
です。ステップ インしようとすると、メソッド呼び出しをステップ オーバーしようとした場合と同じ動作になります。
私が抱えている実際の問題は、エラー処理にあります。次のように変更fooMethodCall
したとします。
public int fooMethodCall()
{
throw new Exception();
}
次のように呼び出します。
try
{
myFoo.fooMethodCall();
}
catch Exception(e)
{
//do something with the exception
}
e.StackTrace を調べると、ほとんど役に立ちません。
at DynamicModule.ns.Wrapped_IFoo_dd88617b4f734f1987dc0099d195ca52.fooMethodCall()
at ConsoleApplication1.Program.Main(String[] args)
in C:\Projects\ConsoleApplication1\Program.cs:line 152
これでわかるのは、fooMethodCall が失敗したということだけです。最初に失敗したか、5 レベル下にネストされたメソッドで失敗した可能性があります。
これについていくつか質問があります。このコードは正しく見えますか? もしそうなら、私がリストした煩わしさ/問題は、メソッド呼び出しをインターセプトするときに避けられないものですか? 私が達成しようとしていることを行うためのより良い方法はありますか?