Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/.net/22.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 将Unity用作AOP框架时缺少完整堆栈跟踪_C#_.net_Unity Container_Aop - Fatal编程技术网

C# 将Unity用作AOP框架时缺少完整堆栈跟踪

C# 将Unity用作AOP框架时缺少完整堆栈跟踪,c#,.net,unity-container,aop,C#,.net,Unity Container,Aop,我注意到当使用Unity作为AoP框架时,尤其是VirtualMethodInterceptor+CallHandler 我得到的堆栈跟踪不包括原始代码。相反,它有一个xxx_wrapper_yyyy类型的类,我假设它是一个从原始类动态继承的类。可以理解,因为没有为动态类编写过源代码,所以它没有报告原始代码中发生错误的行号 我怎样才能改变这个?我需要抛出异常的堆栈跟踪和行号 仅供参考,否则调用处理程序将按预期工作。只是异常缺少发生的原始虚拟方法的行号。不,调用处理程序不包含任何将吞咽或处理异常的

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

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

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

仅供参考,否则调用处理程序将按预期工作。只是异常缺少发生的原始虚拟方法的行号。不,调用处理程序不包含任何将吞咽或处理异常的行。

使用此代码

[TestMethod]
public void应该\u Wrap\u Exception\u ThrownByTarget()完成
{
var container=new UnityContainer();
container.RegisterType(
新的拦截器(),
新的拦截行为());
container.AddNewExtension();
var config=container.Configure();
config.AddPolicy(“1”).AddCallHandler().AddMatchingRule();
var target=container.Resolve();
目标。始终保持稳定(“foo”);
}
公共类始终匹配:IMatchingRule
{
公共布尔匹配(MethodBase成员)
{
返回true;
}
}
公共类异常处理程序:ICallHandler
{
公共整数顺序{get;set;}
公共IMethodReturn调用(IMethodInvoke输入,GetNextHandlereGate getNext)
{
i方法返回r=getNext()(输入,getNext);
if(r.Exception!=null)
{
抛出新的InvalidOperationException(“CallHandler”,r.Exception);
}
返回r;
}
}
公共类目标
{
公共虚拟字符串AlwaysThrows(字符串foo)
{
抛出新异常(“Boom!”);
}
}
我得到一个像这样的stacktrace

   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)
C:\VisualStudio\Evaluation\UnityExceptionSpect\Target.cs中UnityExceptionSpect.Target.AlwaysThrows(字符串foo)处的

在DynamicModule.ns.Wrapped\u Target\u c49f840ef38c41d7b4d5956223e95f73.\u 0(i方法调用输入,获取下一个tinterception行为或删除获取下一个)
很抱歉格式不好


它肯定包含异常的原始源,尽管它被生成的类型的神秘信息弄糊涂了。

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

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

试着想出一个更好的(可靠的)设计来避免使用拦截:-)不知道,我相信AOP是对可靠的补充,而不是与之矛盾。如果你需要拦截,你的系统中缺少了一个抽象。在我看来,您应该能够用一个泛型装饰器装饰一组相关的类。执行此操作时,不需要拦截。举个例子,你以前用过它。装饰图案。有它的优点,但不是到处都有。在“绿地”项目上也更好。AoP更强大,在许多情况下都是有效的解决方案。在我的例子中,这实际上是首选的解决方案-更少的代码,更少的更改,更少的重写。塞巴斯蒂安,这太棒了,我要尝试一下,但看起来这就是我一直在寻找的答案!谢谢您不应该在调用处理程序中抛出异常。相反,如果您让该方法正常返回,那么您的常规异常应该简单地公开。在过去,我只看到在调用处理程序/行为本身崩溃时出现模糊异常。通常是的,这是正确的。在这种情况下,没有堆栈跟踪的原因是Unity管道没有将原始异常携带到管道上——因此,不管怎样,您关心的是这里的一个问题。我对这种方法没有任何问题,因为我唯一使用AOP的时候是在我管理的管道中(没有其他框架依赖它)。如果您需要将其与其他框架联系起来,您可能希望使用基于抛出的框架的反射来构造新的异常。您忽略了一点,即在这个场景中,Unity的AOP将异常更改为通用异常。因此,创建一个新的异常并返回该异常是获取堆栈中异常的任何细节所必需的。新异常是不同类型还是相同类型取决于您的需要和使用。需要重申的是:“Unity管道不会将最初的异常带到管道上,因此您的担心在这里是个问题”