You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

.NET Core类库中调用依赖注入对象的正确方式

针对你的场景,咱们一步步拆解最佳实现方式:

最佳实现:构造函数注入(强烈推荐)

这是依赖注入(DI)的核心实践,完全贴合控制反转(IoC)和显式依赖原则,也是.NET Core生态的标准做法。具体操作非常直接:

  1. 修改Libary2.Libary1Dependency的构造函数,把Libary2.ILibary2Dependency作为参数注入
  2. 在需要调用的方法里直接使用这个注入的实例

代码示例:

// Libary2.Libary1Dependency的具体实现
public class Libary1Dependency : ILibary1Dependency
{
    private readonly ILibary2Dependency _lib2Dependency;

    // 通过构造函数显式注入依赖
    public Libary1Dependency(ILibary2Dependency lib2Dependency)
    {
        _lib2Dependency = lib2Dependency ?? throw new ArgumentNullException(nameof(lib2Dependency));
    }

    public void YourMethodNeedingLib2()
    {
        // 直接使用注入的实例调用方法
        _lib2Dependency.DoRequiredOperation();
    }
}

由于你已经在主应用的DI配置中注册了Libary2.ILibary2Dependency

service.AddTransient<Libary2.ILibary2Dependency, Libary2.Libary2Dependency>();

DI容器会自动解析并注入这个依赖,不需要额外配置。这种方式的优势很明显:

  • 显式声明依赖,代码可读性拉满,别人一看就知道这个类需要什么才能工作
  • 完全复用DI的生命周期管理(比如你用的Transient,每次都会创建新实例)
  • 单元测试时可以轻松MockILibary2Dependency,不用操心真实实现的复杂依赖
  • 符合开闭原则,后续替换ILibary2Dependency的实现,不需要修改Libary1Dependency的代码

不推荐:直接实例化(new)

直接写new Libary2.Libary2Dependency(property1, property2...)是不可取的,问题包括:

  • 硬编码依赖具体实现,违反了依赖倒置原则(应该依赖抽象而非具体类)
  • 完全脱离DI容器的管理,如果后续Libary2Dependency的构造函数新增依赖,你得手动修改所有new的地方
  • 单元测试时无法Mock这个依赖,测试难度直接翻倍
  • 破坏了DI带来的解耦优势,组件之间的耦合度急剧上升

不推荐:注入IServiceCollection/IServiceProvider

在构造函数中注入IServiceCollection或者IServiceProvider属于服务定位器模式,虽然能拿到依赖,但存在明显弊端:

  • 隐藏了真实依赖,从构造函数根本看不出Libary1Dependency需要ILibary2Dependency
  • 代码变得冗余复杂,需要手动从容器中获取服务
  • 单元测试时需要模拟整个DI容器,测试成本大幅提高
  • 违反了显式依赖原则,这是DI模式要避免的典型反模式

是否需要额外NuGet包?

完全不需要!.NET Core自带的Microsoft.Extensions.DependencyInjection已经完全满足你的需求。除非你有非常复杂的DI场景(比如属性注入、多条件注册等),但属性注入一般只适合框架级组件,不推荐用于业务逻辑。如果真的需要扩展能力,可以考虑AutofacStructureMap这类第三方DI容器,但对你当前的场景来说,原生DI足够用,没必要引入额外依赖。

总结一下:优先选择构造函数注入,这是最符合DI设计原则的最佳实践,既简单又能保证代码的可维护性和可测试性。

内容的提问来源于stack exchange,提问作者Xaphann

火山引擎 最新活动