3

我注意到当使用 Unity 作为 AoP 框架时,尤其是 VirtualMethodInterceptor + CallHandler。

我得到的堆栈跟踪不包括原始代码。相反,它有一个 xxx_wrapper_yyyy 类型的类,我假设它是一个从原始类动态继承的类。可以理解,由于没有为动态类编写源代码,因此它没有报告原始代码中发生错误的行号。

我怎样才能改变这个?我需要抛出异常的堆栈跟踪和行号。

仅供参考,呼叫处理程序正在按预期工作。唯一的例外是缺少发生它的原始虚拟方法的行号。并且没有调用处理程序不包含任何会吞下或处理异常的行。

4

2 回答 2

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)

抱歉格式不好...

它肯定包含异常的原始来源,尽管它被有关生成类型的神秘信息所混淆。

于 2012-10-03T11:22:33.427 回答
0

只需将返回值的 Exception 设置为新的异常即可。例如:

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;
}
于 2014-03-31T16:38:47.147 回答