2012-08-01 3 views
5

Wir untersuchen die Verwendung von Unity für Protokollierungs-Service-Methoden mit Interception. Ein Problem besteht jedoch darin, dass die vollständige Stack-Ablaufverfolgung an der Aufruf-Site nicht verfügbar ist; es ist nur innerhalb eines Interceptor-Aufrufs verfügbar.Full-Stack-Trace für abgefangene Methoden am Standort des Aufrufs in Unity

Hier ist ein Beispiel-Setup:

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); 
     } 

    } 
} 

Hier ist die Ausgabe Konsole aus dem Programm ausgeführt wird:

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 

Der Stack-Trace in dem Interceptor ist in Ordnung und wird für die Anmeldung auf der Service-Ebene genügen. Wir verlieren jedoch alles nach dem Interception-Proxy-Aufruf an der Aufruf-Site;

ich die Ausnahme in dem Interceptor in einer Service oder so wickeln kann, und das wird in der inneren Ausnahme den Call-Stack halten, aber das führt zu umständlich Logging und Debug-Inspektionsszenarien (wenn auch weniger umständlich als die Spur völlig zu verlieren).

Ich habe auch bemerkt, dass wir mehr oder weniger bekommen, was wir wollen, wenn wir den TransparentProxyInterceptor verwenden, aber das wird als langsamer als InterfaceInterception festgestellt, und das löst Alarmglocken für einige Gruppen aus.

Gibt es eine sauberere Möglichkeit, eine vollständige Stack-Trace mit Unity Abfangen an der Aufruf-Site auf einem Proxy zu erhalten?

Antwort

2

In .NET 4.5 wird es ExceptionDispatchInfo für diesen Zweck geben.

Für alle anderen Versionen, die Sie diese Frage sehen:
In C#, how can I rethrow InnerException without losing stack trace?

+0

Danke, das Antwort funktioniert gut für unsere Zwecke! – Nick

+1

@Nick - kannst du mehr sagen, was du getan hast? –

+0

Ich habe keinen Zugriff auf diesen Code mehr, aber es gab "ret.Exception" in meiner ursprünglichen Frage zu den Beispielmethoden aus dem SO-Link in der akzeptierten Antwort (effektiv 'PreserveStackTrace (ret.Exception)' von [hier ] (http://stackoverflow.com/a/2085377)). Ich habe auch den reflektionsbasierten Ansatz später in der Kommentarzeichenfolge versucht, die an .NET 4.0 arbeitete. Wenn wir in .NET 4.5 umgezogen wären, während ich noch daran arbeitete, hätte ich mich stattdessen mit ExceptionDispatchInfo beschäftigt. – Nick

Verwandte Themen