首页 > 解决方案 > 在 .NET Core 2.2 中自动解决依赖关系

问题描述

.NET Core 2.2 中的内置依赖注入框架是否无法解析依赖并在创建实例时自动注入实例?或者注入依赖的唯一方法是在创建新实例时显式解决它?

我正在构建一个类库项目(因此,[FromServices] 属性对我来说不是一个选项),在我看来,我几乎必须在每个类的构造函数中传递 IServiceProvider。

我误解了什么吗?

注意:代码片段只是说明性的。

public class A
{
    public A()
    {

    }

    public void DoSomethingWithB()
    {
        var b = new B(// To resolve IConfiguration here, I need IServiceProvider. That means I will need to inject IServiceProvider in class A first. Will it go on nesting like this everywhere?);
    }
}

public class B
{
    private IConfiguration _config;
    public B(IConfiguration config)
    {
        _config = config;
    }
    public void DoWork()
    {
        // Use _config here.
    }
}

标签: asp.net-coredependency-injection.net-core

解决方案


您的类库项目根本不应该了解依赖注入。相反,您应该做的是确保每个类在构造函数中接受其所有依赖项,如下所示:

public void MyClass(IMyDependency dependency)

它适用于被称为Composition Root确保一切都从顶部解决的事情。例如,在 ASP.NET 的情况下,框架本身将调用Resolve获取Controller并组成整个对象树,您的类将直接或间接依赖于控制器。

这个原则有个花哨的名字叫“好莱坞原则”:不要叫我们,我们叫你。如果您将自己解决依赖关系(即“调用它们”),那么您正在做一些Service Locator被认为是反模式的调用。因此,相反,您依赖某人(即“他们给您打电话”)将在某个初始入口点在您的类中注入正确的依赖项。

此外,当您想要进行单元测试、更改 DI 容器等时,任何意识到 DI 容器的类库设计都会在未来导致许多问题。所以最好的选择是对那里的容器一无所知。

PS 微软本身在我眼中实际上犯了一个错误,他们将很多库与 DI 容器 ( IServiceCollection) 捆绑在一起。例如,日志库、HTTP 工厂等都依赖这个 DI 容器来完成这项工作,几乎不可能切换到另一个容器。

我知道这将使某人在不太了解 DI 的情况下使用它变得更加容易,但从长远来看,它确实会限制您并使例如单元测试更加麻烦。


推荐阅读