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

非DI创建的MS类如何获取DI注入的AEO类实例?

如何在手动实例化的类中获取DI容器里的Keyed注册服务?

问题背景

我们维护的一个老旧服务架构糟糕、体量庞大,但因计划弃用暂不重构。现在需要修改类MS的某个方法,替换原有的直接HTTP调用为使用已有的AEO类实现。AEO继承自抽象类EC,依赖多个DI注入的字段,且已通过以下方式注册到DI容器:

builder.RegisterType<AEO>().Keyed<EC>(MCType.AEO).SingleInstance().WithAttributeFiltering();

但MS并非通过DI创建,而是在Program.cs中完成DI注册后,手动传入参数实例化的。当前面临的困境:

  • 直接new AEO(...)会因缺少DI注入的依赖参数无法实现
  • 若给MS添加AEO或EC的构造依赖,手动实例化MS时需要传入该依赖,而我们不想修改现有的实例化逻辑

可行解决方案

方案1:从DI容器解析服务后传入MS(优先推荐)

既然MS是在Program.cs中手动实例化的,此时DI容器已完成注册,可直接解析出AEO实例,再传入MS的构造函数或方法中。

操作步骤:
  1. 修改MS的构造函数,新增EC类型的参数(保留原有参数):
public class MS
{
    private readonly EC _aeo;

    public MS(原有参数类型 param1, 原有参数类型 param2, EC aeo)
    {
        _aeo = aeo;
        // 原有构造逻辑
    }

    // 若不想修改构造函数,也可新增一个注入方法
    public void InjectAEO(EC aeo)
    {
        _aeo = aeo;
    }
}
  1. 在Program.cs中实例化MS前,先从容器解析Keyed服务:
var container = builder.Build();
// 解析Keyed注册的EC实例
var aeoInstance = container.ResolveKeyed<EC>(MCType.AEO);
// 传入aeo实例,完成MS的手动实例化
var ms = new MS(原有参数1, 原有参数2, aeoInstance);

该方案侵入性最小,逻辑直接,完全适配临时修改的需求。

方案2:通过静态容器访问器间接获取服务(应急方案)

如果无法修改MS的构造或实例化传入参数,可通过静态类封装DI容器,让MS直接从静态类中解析服务。注意:此方案会增加耦合,仅适合临时过渡。

操作步骤:
  1. 添加静态容器访问类:
public static class StaticContainer
{
    public static IContainer Instance { get; set; }
}
  1. 在Program.cs构建容器后赋值:
var container = builder.Build();
StaticContainer.Instance = container;
  1. 在MS的目标方法中解析服务:
public class MS
{
    public void TargetMethod()
    {
        var aeo = StaticContainer.Instance.ResolveKeyed<EC>(MCType.AEO);
        // 使用aeo替换原HTTP调用逻辑
    }
}

方案3:用工厂模式封装MS实例化(过渡优化方案)

如果后续还有类似修改需求,可将MS的实例化逻辑封装到工厂类中,由工厂从DI容器获取依赖后创建MS,既不破坏现有调用逻辑,又符合DI原则。

操作步骤:
  1. 创建MS工厂类,注入所需的EC实例:
public class MSFactory
{
    private readonly EC _aeo;

    // 借助KeyFilter特性自动匹配Keyed注册的服务
    public MSFactory([KeyFilter(MCType.AEO)] EC aeo)
    {
        _aeo = aeo;
    }

    public MS CreateMS(原有参数类型 param1, 原有参数类型 param2)
    {
        return new MS(param1, param2, _aeo);
    }
}
  1. 将工厂注册到DI容器:
builder.RegisterType<MSFactory>().SingleInstance();
  1. 在Program.cs中通过工厂创建MS:
var container = builder.Build();
var msFactory = container.Resolve<MSFactory>();
var ms = msFactory.CreateMS(原有参数1, 原有参数2);

方案选择建议

  • 优先选方案1:逻辑直接、侵入性小,完全适配临时修改场景
  • 若无法修改MS的构造/实例化逻辑,选方案2应急
  • 后续有多次修改需求时,选方案3更整洁规范

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.08 22:11:06