我注意到当使用Unity作为AoP框架时,特别是VirtualMethodInterceptor + CallHandler。
我得到的堆栈跟踪不包含原始代码。相反,它有一个xxx_wrapper_yyyy类的类,我假设它是一个动态继承原始类的类。可以理解的是,由于没有为动态类编写源代码,因此不会报告原始代码中发生错误的行号。
我该怎么改变?我需要抛出异常的堆栈跟踪和行号。
FYI呼叫处理程序正在按预期工作。只是例外是缺少原始虚拟方法的行号。并且调用处理程序不包含任何会吞下或处理异常的行。
答案 0 :(得分:2)
使用此代码
[TestMethod]
public void Should_Wrap_Exception_ThrownByTarget()
{
var container = new UnityContainer();
container.RegisterType<Target>(
new Interceptor<VirtualMethodInterceptor>(),
new InterceptionBehavior<PolicyInjectionBehavior>());
container.AddNewExtension<Interception>();
var config = container.Configure<Interception>();
config.AddPolicy("1").AddCallHandler<ExceptionHandler>().AddMatchingRule<AlwaysMatches>();
var target = container.Resolve<Target>();
target.AlwaysThrows("foo");
}
public class AlwaysMatches : IMatchingRule
{
public bool Matches(MethodBase member)
{
return true;
}
}
public class ExceptionHandler : ICallHandler
{
public int Order { get; set; }
public IMethodReturn Invoke(IMethodInvocation input, GetNextHandlerDelegate getNext)
{
IMethodReturn r = getNext()(input, getNext);
if (r.Exception != null)
{
throw new InvalidOperationException("CallHandler", r.Exception);
}
return r;
}
}
public class Target
{
public virtual string AlwaysThrows(string foo)
{
throw new Exception("Boom!");
}
}
我得到一个看起来像这样的堆栈跟踪
at UnityExceptionAspect.Target.AlwaysThrows(String foo) in C:\VisualStudio\Evaluation\UnityExceptionAspect\Target.cs:line 9
at DynamicModule.ns.Wrapped_Target_c49f840ef38c41d7b4d5956223e95f73.<AlwaysThrows_DelegateImplementation>__0(IMethodInvocation inputs, GetNextInterceptionBehaviorDelegate getNext)
抱歉格式不佳......
它肯定包含异常的原始来源,尽管它被生成类型的密码信息混淆。
答案 1 :(得分:0)
只需将返回值的异常设置为新的异常即可。例如:
public IMethodReturn Invoke(IMethodInvocation input, GetNextHandlerDelegate getNext)
{
IMethodReturn r = getNext()(input, getNext);
if (r.Exception != null) r.Exception = new Exception("NameOfInterceptor", r.Exception);
return r;
}