5

Unityを使用して、インターセプトを使用したロギングサービスメソッドを処理することを検討しています。ただし、1つの懸念は、完全なスタックトレースが呼び出しサイトで利用できないことです。インターセプターコール内でのみ使用できます。

設定例は次のとおりです。

public interface IExceptionService
{
    void ThrowEx();
}

public class ExceptionService : IExceptionService
{
    public void ThrowEx()
    {
        throw new NotImplementedException();
    }
}

public class DummyInterceptor : IInterceptionBehavior
{
    public IEnumerable<Type> GetRequiredInterfaces()
    {
        return Type.EmptyTypes;
    }

    public IMethodReturn Invoke(IMethodInvocation input, GetNextInterceptionBehaviorDelegate getNext)
    {
        IMethodReturn ret = getNext()(input, getNext);
        if (ret.Exception != null)
            Console.WriteLine("Interceptor: " + ret.Exception.StackTrace + "\r\n");
        return ret;
    }

    public bool WillExecute
    {
        get { return true; }
    }
}

class Program
{
    static void Main(string[] args)
    {
        IUnityContainer container = new UnityContainer();
        container.AddNewExtension<Interception>();

        container.RegisterType<IExceptionService, ExceptionService>(
            new Interceptor<InterfaceInterceptor>(),
            new InterceptionBehavior<DummyInterceptor>());

        try
        {
            container.Resolve<IExceptionService>().ThrowEx();
        }
        catch (Exception e)
        {
            Console.WriteLine("Call Site: " + e.StackTrace);
        }

    }
}

そのプログラムの実行によるコンソール出力は次のとおりです。

Interceptor:
at ConsoleDemo.ExceptionService.ThrowEx() in    C:\code\ServiceDemo\ConsoleDemo\Program.cs:line 25
at DynamicModule.ns.Wrapped_IExceptionService_248fe3264f81461f96d34670a0a7d45d.<ThrowEx_DelegateImplementation>__0(IMethodInvocation inputs, GetNextInterceptionBehaviorDelegate getNext)

Call Site:
at DynamicModule.ns.Wrapped_IExceptionService_248fe3264f81461f96d34670a0a7d45d.ThrowEx()
at ConsoleDemo.Program.Main(String[] args) in C:\code\ServiceDemo\ConsoleDemo\Program.cs:line 63

インターセプターのスタックトレースは問題なく、サービスレベルでのログ記録には十分です。ただし、コールサイトでの傍受プロキシコールを過ぎるとすべてが失われます。

ServiceExceptionなどのインターセプターで例外をラップできます。これにより、呼び出しスタックが内部例外に保持されますが、ログ記録とデバッグ検査のシナリオが厄介になります(ただし、トレースを完全に失うよりも厄介ではありません)。

また、TransparentProxyInterceptorを使用すると、多かれ少なかれ必要なものが得られることに気付きましたが、これはInterfaceInterceptionよりも低速であり、一部のグループでアラームベルがトリガーされます。

プロキシの呼び出しサイトでUnityインターセプトを使用して完全なスタックトレースを取得するためのよりクリーンな方法はありますか?

4

1 に答える 1

2

.NET 4.5では、この目的のためにExceptionDispatchInfoがあります。

他のすべてのバージョンでは、次の質問が表示されます
。C#で、スタックトレースを失うことなくInnerExceptionを再スローするにはどうすればよいですか?

于 2012-08-02T05:21:14.077 に答える