You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何通过依赖注入在嵌套类链的底层类中获取所需服务?

解决方案

最优方案:使用依赖注入(DI)容器托管所有实例

构造函数参数膨胀问题的根源是手动通过new关键字创建实例,把实例化控制权交给DI容器即可从根源解决该问题,无需在A、B中传递任何不需要的服务参数。

实现步骤

  • 调整A、B、C的构造函数,仅注入自身直接依赖的对象:
public class A
{
    private readonly B _classB;
    // 仅注入直接依赖的B,不需要感知ILogger
    public A(B classB)
    {
        _classB = classB;
    }
}

public class B
{
    private readonly C _classC;
    // 仅注入直接依赖的C,不需要感知ILogger
    public B(C classC)
    {
        _classC = classC;
    }
}

public class C
{
    private readonly ILogger<C> _logger;
    // 仅注入自身需要的ILogger
    public C(ILogger<C> logger)
    {
        _logger = logger;
    }
}
  • 在DI容器中注册所有类型,以ASP.NET Core为例:
// Program.cs 中注册
builder.Services.AddTransient<A>();
builder.Services.AddTransient<B>();
builder.Services.AddTransient<C>();
// ILogger 是框架默认注册的,无需手动注册
  • 后续需要使用A时,直接从容器中获取A的实例即可,容器会自动按A→B→C的依赖链完成所有实例的创建和依赖注入,全程不需要手动传参,A、B完全感知不到ILogger的存在。

兼容方案:服务定位器模式(不推荐,仅作为无法调整上层实例化逻辑时的兜底方案)

如果A、B的代码无法修改,必须保留手动new的逻辑,可以通过全局服务定位器获取ILogger实例:

public class C
{
    private readonly ILogger<C> _logger;
    public C()
    {
        // 从全局服务提供者获取实例,AppContext.ServiceProvider需要提前配置为全局DI容器实例
        _logger = AppContext.ServiceProvider.GetRequiredService<ILogger<C>>();
    }
}

注意:该模式属于依赖注入反模式,会隐藏类的真实依赖,提升单元测试的难度,仅在迫不得已的场景下使用。


内容的提问来源于stack exchange,提问作者Антон Юдин

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.26 19:15:08