2012-08-01 7 views
5

Szukamy możliwości wykorzystania Unity do obsługi metod logowania przy przechwytywaniu. Jednak jedną z obaw jest to, że śledzenie całego stosu nie jest dostępne na stronie połączenia; jest dostępna tylko w połączeniu z przechwytywaczem.Śledzenie pełnego stosu dla przechwyconych metod na stronie wywołania w Unity

Oto przykład konfiguracji:

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

    } 
} 

Oto wyjście konsoli uruchamianie tego programu:

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 

Ślad stosu w kolektora jest w porządku i wystarczą do logowania na poziomie serwisowym. Jednakże tracimy wszystko poza połączeniem proxy przechwytywania na stronie wywołania;

Mogę zawrzeć wyjątek w przechwytywaczu w wyjątku ServiceException lub innym takim, który będzie utrzymywał stos wywołań w wewnętrznym wyjątku, ale prowadzi to do niezręcznych scenariuszy rejestrowania i debugowania inspekcji (choć mniej kłopotliwe niż całkowite utracenie śladu).

Zauważyłem również, że otrzymujemy mniej więcej to, co chcemy, gdy używamy TransparentProxyInterceptor, ale jest to zauważane jako wolniejsze niż InterfaceInterception, i które wyzwala dzwonki alarmowe dla niektórych grup.

Czy istnieje jakiś czystszy sposób na uzyskanie pełnego śledzenia stosu przy przechwytywaniu Unity w witrynie połączenia na serwerze proxy?

Odpowiedz

2

W .NET 4.5 będzie w tym celu ExceptionDispatchInfo.

Dla wszystkich innych wersjach można zobaczyć to pytanie:
In C#, how can I rethrow InnerException without losing stack trace?

+0

Dzięki, że odpowiedź działa świetnie dla naszych celów! – Nick

+1

@Nick - czy możesz powiedzieć więcej, co robiłeś? –

+0

Nie mam już dostępu do tego kodu, ale było przekazywanie 'ret.Exception' w moim oryginalnym pytaniu do przykładowych metod z linku SO w zaakceptowanej odpowiedzi (skutecznie' PreserveStackTrace (ret.Exception) 'from [here ] (http://stackoverflow.com/a/2085377)). Spróbowałem również podejścia opartego na refleksji później w ciągu komentarza, który pracował nad .NET 4.0. Gdybyśmy przenieśli się do .NET 4.5, podczas gdy wciąż nad nim pracowałem, szukałbym zamiast tego opcji ExceptionDispatchInfo. – Nick

Powiązane problemy