We're looking into using Unity to handle logging service methods with interception. However, one concern is that the full stack trace is not available at the call site; its only available within an interceptor call.
Here's an example 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);
}
}
}
Here's the console output from running that program:
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
The stack trace in the interceptor is fine and will suffice for logging at the service level. However, we lose everything past the interception proxy call at the call site;
I can wrap the exception in the interceptor in a ServiceException or some such, and that will keep the call stack in the inner exception, but that leads to awkward logging and debug inspection scenarios (though less awkward than losing the trace entirely).
I've also noticed we get more or less what we want when we use the TransparentProxyInterceptor, but that is noted as being slower than InterfaceInterception, and that triggers alarm bells for some groups.
Is there any cleaner way to get a full stack trace with Unity interception at the call site on a proxy?
In .NET 4.5 there will be ExceptionDispatchInfo for this purpose.
For all other versions you can see this question:
In C#, how can I rethrow InnerException without losing stack trace?
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With