0

我想像这样使用我的子类:

throw new MyCustomException()

每当调用它时,我都想用相关 id 包装它,该相关 id 应该由服务注入。我想将它注入基类以避免那样写

throw new MyCustomException(correlationID)

但我不知道在应该通过构造函数注入完成的情况下如何做到这一点。

换句话说,我想将依赖注入到无参数构造函数中。类似的东西

class MyBaseException()
{
    private IWorkingContext workingContext;
    public MyBaseException()
    {
        this.workingContext = workingContext;
    }
}

是的,我知道通常我需要这样做:

public MyBaseException(IWorkingContext workingContext)

但是希望这个构造函数 MyBaseException(IWorkingContext workingContext) 在没有参数的情况下被调用,所以最后我可以使用我的子类,比如 MyCustomException() 并将 workingContext 包装在其中。

我的温莎注册:

container.Register(Component.For<IWorkingContext>().ImplementedBy<WorkingContext>().LifeStyle.PerWebRequest)

我试过这种方法:

var containerAccessor = HttpContext.Current.ApplicationInstance as IContainerAccessor;
var container = containerAccessor.Container;
var operationContext = container.Resolve<IWorkingContext>();

但它不起作用(新对象由温莎创建)。

4

1 回答 1

0

当您new出现异常或任何类时,它不会由您的 IOC 容器管理,因此它根本无法帮助您丰富您的异常类。

您可以做几件事,但是,其中一些质量有问题:

  1. 在异常的构造函数中使用服务定位器模式(非常恶心)
  2. 使用工厂方法/类 - 在您的 IOC 容器中注册并依赖于IWorkingContext- 这实际上会给您一个异常实例来抛出堆栈。这仍然意味着您的异常将有一个构造函数接受依赖项,但抛出异常的类不知道或不需要知道这一点。(我会推荐这种方法)

  3. 一个专门的类,位于您的域的外围,旨在捕获并随后丰富堆栈中冒泡的任何异常。这是有风险的,原因如下:

    • 不正确的实现会让你失去异常的上下文(主要是堆栈跟踪信息)
    • 您现在几乎强制每个组件忽略异常,因为您迫切需要异常的上下文以用于记录或其他目的。
  4. 质疑您要采用的整个方法。为什么不使用上下文丰富日志时的异常,而不是在异常时添加此元数据?

就个人而言,我认为 2 是最可行的选择,但如果您在整个应用程序中有很多不同的自定义异常,它可能会很快失控。无论您选择哪个选项,我都会始终查看 4,因为有时您要解决的问题是错误的问题。

于 2017-12-13T07:07:34.643 回答