Мы рассматриваем возможность использования Unity для обработки методов службы ведения журналов с перехватом. Однако одна проблема заключается в том, что полная трассировка стека недоступна на месте вызова; он доступен только в вызове перехватчика.
Вот пример настройки:
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 на месте вызова на прокси?