2012-08-01 12 views
5

Stiamo cercando di utilizzare Unity per gestire i metodi di servizio di registrazione con l'intercettazione. Tuttavia, una preoccupazione è che la traccia dello stack completo non è disponibile nel sito di chiamata; è disponibile solo all'interno di una chiamata interceptor.Traccia stack completo per i metodi intercettati sul sito di chiamata in Unity

Ecco un esempio di configurazione:

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

    } 
} 

Ecco l'output della console di eseguire quel programma:

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 

L'analisi dello stack nel intercettore sta bene e sarà sufficiente per l'accesso a livello di servizio. Tuttavia, perdiamo tutto oltre la chiamata proxy di intercettazione sul sito di chiamata;

Posso avvolgere l'eccezione nell'intercettore in una ServiceException o qualcosa del genere, e questo manterrà lo stack di chiamate nell'eccezione interna, ma questo porta a scenari di controllo di debuging e di registrazione scomodi (anche se meno complicati di perdere completamente la traccia).

Ho anche notato che otteniamo più o meno quello che vogliamo quando usiamo il TransparentProxyInterceptor, ma che è notato come più lento di InterfaceInterception, e che fa scattare campane d'allarme per alcuni gruppi.

Esiste un modo più semplice per ottenere una traccia stack completa con l'intercettazione Unity sul sito di chiamata su un proxy?

risposta

2

In .NET 4.5 ci sarà ExceptionDispatchInfo per questo scopo.

Per tutte le altre versioni è possibile vedere questa domanda:
In C#, how can I rethrow InnerException without losing stack trace?

+0

Grazie, che funziona alla grande risposta per i nostri scopi! – Nick

+1

@Nick - puoi dire di più su cosa hai finito? –

+0

Non ho più accesso a quel codice, ma passava 'ret.Exception' nella mia domanda originale ai metodi di esempio dal link SO nella risposta accettata (in effetti' PreserveStackTrace (ret.Exception) 'da [qui ] (http://stackoverflow.com/a/2085377)). Ho anche provato l'approccio basato sulla riflessione più avanti nella stringa di commenti, che stava lavorando su .NET 4.0. Se ci fossimo trasferiti su .NET 4.5 mentre stavo ancora lavorando su di esso, avrei cercato invece di usare ExceptionDispatchInfo. – Nick

Problemi correlati