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

控制器外的依赖注入:多层对象如何获取MainProgram实例?

在ASP.NET Core 6中解决深层嵌套对象的依赖注入问题

核心解决方案:让DI容器接管所有依赖的创建与传递

不要手动new需要依赖的对象,而是将所有涉及的类型(包括TestOperation及其子对象)注册到DI容器,让容器自动解析整个依赖链,无需手动传递MainProgram实例。

步骤1:注册所有依赖类型到服务容器

除了已注册的MainProgram,把TestOperation、它的子对象等所有需要依赖注入的类型都注册到容器中,根据业务场景选择合适的生命周期(Singleton/Scoped/Transient):

// 注册MainProgram为Singleton
builder.Services.AddSingleton<MainProgram>(sp => new MainProgram(1000));

// 注册TestOperation(生命周期根据实际业务调整)
builder.Services.AddSingleton<TestOperation>();

// 如果TestOperation有子对象(比如TestSubOperation),同样注册
builder.Services.AddSingleton<TestSubOperation>();

步骤2:通过构造注入获取实例,而非手动new

在需要使用TestOperation的地方(比如控制器),直接通过构造函数注入TestOperation,DI容器会自动完成所有依赖的注入,包括将MainProgram传递给TestOperation(以及它的子对象):

[ApiController]
[Route("api/[controller]")]
public class MyController : ControllerBase
{
    private readonly TestOperation _testOperation;

    // 构造注入TestOperation,容器自动处理其依赖链
    public MyController(TestOperation testOperation)
    {
        _testOperation = testOperation;
    }

    [HttpGet]
    public IActionResult Get()
    {
        // 直接使用_testOperation,无需关心MainProgram的传递逻辑
        return Ok(_testOperation.DoSomething());
    }
}

步骤3:深层子对象的依赖处理

如果TestOperation的子对象(比如TestSubOperation)需要MainProgram,只需在子对象的构造函数中声明依赖,同时将子对象注册到容器即可:

// 深层子对象,依赖MainProgram
public class TestSubOperation
{
    private readonly MainProgram _mainProgram;

    public TestSubOperation(MainProgram mainProgram)
    {
        _mainProgram = mainProgram;
    }

    public void DoSubTask()
    {
        // 直接使用_mainProgram实例
    }
}

// TestOperation依赖TestSubOperation
public class TestOperation
{
    private readonly TestSubOperation _subOperation;

    public TestOperation(TestSubOperation subOperation)
    {
        _subOperation = subOperation;
    }

    public string DoSomething()
    {
        _subOperation.DoSubTask();
        return "Operation completed";
    }
}

容器会自动解析整个依赖链:MainProgram → TestSubOperation → TestOperation,所有层级的对象都能自动获取MainProgram实例,完全无需手动传参。

特殊场景:动态创建对象的处理

如果需要在运行时动态创建对象(而非通过构造注入),可以使用ActivatorUtilities.CreateInstance,它会从DI容器中自动获取所需的依赖:

public class SomeService
{
    private readonly IServiceProvider _serviceProvider;

    public SomeService(IServiceProvider serviceProvider)
    {
        _serviceProvider = serviceProvider;
    }

    public void CreateTestOperationDynamically()
    {
        // 自动注入所需依赖,无需手动传递MainProgram
        var testOperation = ActivatorUtilities.CreateInstance<TestOperation>(_serviceProvider);
        testOperation.DoSomething();
    }
}

注意事项

  • 优先使用构造注入,避免直接通过IServiceProvider获取依赖(服务定位器模式),这样代码更易测试、维护,也更符合DI的设计原则。
  • 确保所有需要依赖的类型都正确注册到容器,否则会触发InvalidOperationException(找不到对应服务)的错误。

内容的提问来源于stack exchange,提问作者Паша Мостов

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.19 11:10:32