Dependency injection 应在何处(层)使用DI?

Dependency injection 应在何处(层)使用DI?,dependency-injection,inversion-of-control,Dependency Injection,Inversion Of Control,是否存在使用DI不好的层?在一个示例中,用户提到DI应仅在UI层中使用。DI应在一个组件依赖于另一个组件的任何情况下使用,无论是UI-->业务、业务-->数据访问还是其他。我不认为它应该只用于UI,只是DI使测试UI更容易,因此似乎有更多的直接好处。我不同意这种说法。你前面提到的问题不是不正确就是你误解了 DI当然不仅仅在UI层。我只同意在控制器是视图层的一部分的条件下这样做 只要可以正确提供依赖项,就可以使用DI 您选择使用工厂还是DI解决方案是您的选择。我认为您可能误解了提供的答案。除非我弄

是否存在使用DI不好的层?在一个示例中,用户提到DI应仅在UI层中使用。

DI应在一个组件依赖于另一个组件的任何情况下使用,无论是UI-->业务、业务-->数据访问还是其他。我不认为它应该只用于UI,只是DI使测试UI更容易,因此似乎有更多的直接好处。

我不同意这种说法。你前面提到的问题不是不正确就是你误解了

DI当然不仅仅在UI层。我只同意在控制器是视图层的一部分的条件下这样做

只要可以正确提供依赖项,就可以使用DI


您选择使用工厂还是DI解决方案是您的选择。

我认为您可能误解了提供的答案。除非我弄错了,否则产生这个问题的一句话是:“您也不应该在应用程序的业务层中创建与DI框架的依赖关系。”

我相信他说的是,所有依赖信息/映射都应该在应用程序的最高级别创建。这并不是说依赖关系不会出现在应用程序的所有层中,只是较低的层不负责设置映射

如果我的解释是正确的,那么我同意他的观点——在应用程序的表面设置依赖关系映射。相反,如果他说您永远不应该解决较低层中的依赖关系,那么我就不同意了。

依赖关系注入(DI)应该在任何地方使用。但是,请注意,DI只是一组模式,而不是一个框架或库。考虑DI的最佳方式是,它是由构造函数注入启用的松散耦合代码。您可以编写或使用

接下来的问题是,组件应该在哪里组成?这可能就是原始语句的意思:-UI或(web)服务接口。这就是我所说的合成根。它使代码的其余部分保持模块化和灵活性

在合成词根处,您可以使用穷人的DI或合适的DI容器。我强烈建议您使用DI容器,但这不是必需的

为了说明我所说的DI,下面是一个示例:

public class Foo : IFoo
{
    private readonly IBar bar;

    public Foo(IBar bar)
    {
        if (bar == null)
        {
            throw new ArgumentNullException("bar");
        }

        this.bar = bar;
    }

    public IBaz Baz(ISnafu snafu)
    {
        return this.bar.Snafize(snafu).ToBaz();
    }
}
IBaz实现可以在一个与定义Foo类的库完全分离的库中实现。此外,在堆栈中处于较高位置的消费者不需要了解任何有关Foo和IBar的信息-他们只需要使用IFoo:

public class MyClass : ISomeInterface
{
    private readonly IFoo foo;

    public MyClass(IFoo foo)
    {
        if (foo == null)
        {
            throw new ArgumentNullException("foo");
        }

        this.foo = foo;
    }

    // ...
}

这提供了松散耦合,这是DI的动机。尽可能多地重复。

“仅在最外层编写应用程序”应用程序可能会产生误导。如果您有一个依赖于web服务的web应用程序,那么web服务也可以被视为一个应用程序。所以也许“只在应用程序的边界上编写对象图”听起来更清楚。据我所知,在整个应用程序中可能有多个合成根。web服务是一个单独的应用程序(单独的进程)。它甚至可以在不同的平台上用不同的语言编写。因此,不言而喻,每个应用程序都有一个合成根。