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

嵌套动态对象创建场景下的依赖注入优化方案咨询

嵌套动态对象创建场景下的依赖注入优化方案咨询

看起来你正被深层嵌套对象的依赖传递问题困扰——直接用静态类确实能快速“解决”问题,但长期来看会带来耦合度高、单元测试困难(比如没法轻松替换依赖)、线程安全隐患等一堆麻烦。我给你几个更优雅的方案,你可以根据自己的场景选择:

方案一:依赖注入容器 + 工厂模式(首推)

这个方案最符合依赖注入的设计原则,能清晰管理依赖关系,同时让A类不用关心具体Condition的依赖细节。

步骤1:定义条件工厂

先创建一个工厂类,专门负责创建各种Condition实例,工厂本身通过构造注入拿到所需的依赖:

public interface IConditionFactory
{
    Condition CreatePriceIsHigherCondition(double price);
    // 可以根据需求添加其他条件的创建方法
}

public class ConditionFactory : IConditionFactory
{
    private readonly IPriceList _priceList;

    // 构造注入IPriceList,由DI容器负责传入
    public ConditionFactory(IPriceList priceList)
    {
        _priceList = priceList;
    }

    public Condition CreatePriceIsHigherCondition(double price)
    {
        return new PriceIsHigherCondition(price, _priceList);
    }
}

步骤2:修改A类依赖工厂

让A类依赖工厂接口,而不是直接创建Condition:

public class A
{
    private List<Condition> _conditions = new List<Condition>();
    private readonly IConditionFactory _conditionFactory;

    public A(IConditionFactory conditionFactory)
    {
        _conditionFactory = conditionFactory;
    }

    public void CreateConditionsFromJson()
    {
        // 现在创建条件只需要调用工厂,不用管依赖传递了
        _conditions.Add(_conditionFactory.CreatePriceIsHigherCondition(3.4));
    }
}

步骤3:注册依赖到DI容器

在程序入口(比如Main)把所有依赖注册到DI容器(比如微软自带的Microsoft.Extensions.DependencyInjection,或者Autofac等第三方容器):

static void Main(string[] args)
{
    var services = new ServiceCollection();
    // 注册IPriceList的实现
    services.AddSingleton<IPriceList, PriceList>();
    // 注册工厂
    services.AddSingleton<IConditionFactory, ConditionFactory>();
    // 注册A类(如果A是被其他类依赖,也可以在这里注册)
    services.AddSingleton<A>();

    var serviceProvider = services.BuildServiceProvider();
    // 从容器获取A实例,所有依赖会自动注入
    var a = serviceProvider.GetRequiredService<A>();
}

这个方案的优势是依赖关系清晰,单元测试时可以轻松替换工厂或IPriceList的实现,代码可维护性拉满。

方案二:服务定位器模式(谨慎使用)

这个模式相当于一个全局的DI入口,比静态类灵活,但会隐藏依赖关系,适合老项目改造或者实在没办法的场景。

步骤1:实现服务定位器

public static class ServiceLocator
{
    private static IServiceProvider _serviceProvider;

    // 在程序初始化时传入DI容器
    public static void Initialize(IServiceProvider serviceProvider)
    {
        _serviceProvider = serviceProvider;
    }

    // 获取指定类型的服务
    public static T GetService<T>() where T : notnull
    {
        return _serviceProvider.GetRequiredService<T>();
    }
}

步骤2:初始化并使用

在Main里初始化定位器,然后修改PriceIsHigherCondition的构造:

static void Main(string[] args)
{
    var services = new ServiceCollection();
    services.AddSingleton<IPriceList, PriceList>();
    var serviceProvider = services.BuildServiceProvider();
    ServiceLocator.Initialize(serviceProvider);
}

public class PriceIsHigherCondition : Condition
{
    double _price;
    IPriceList _priceList;

    public PriceIsHigherCondition(double price)
    {
        _price = price;
        // 从服务定位器获取依赖
        _priceList = ServiceLocator.GetService<IPriceList>();
    }

    public override bool IsTrue()
    {
        return _price > _priceList.GetPrice();
    }
}

这样A类里创建条件时就不用传依赖了,但要注意:这个模式会让代码的依赖关系变得不直观,单元测试时需要先初始化定位器,所以除非万不得已,优先选方案一。

方案三:将依赖放到执行上下文

如果你的Condition创建和执行是分离的,可以把依赖放到执行上下文里,只在需要判断的时候传入:

步骤1:定义执行上下文

public abstract class Condition
{
    // 修改IsTrue方法,接收上下文参数
    public abstract bool IsTrue(IExecutionContext context);
}

public interface IExecutionContext
{
    IPriceList PriceList { get; }
}

public class ExecutionContext : IExecutionContext
{
    public IPriceList PriceList { get; }

    public ExecutionContext(IPriceList priceList)
    {
        PriceList = priceList;
    }
}

步骤2:修改条件类

public class PriceIsHigherCondition : Condition
{
    double _price;

    public PriceIsHigherCondition(double price)
    {
        _price = price;
    }

    public override bool IsTrue(IExecutionContext context)
    {
        return _price > context.PriceList.GetPrice();
    }
}

这样创建Condition时不用传依赖,只有在执行判断的时候才传入上下文。这个方案适合条件创建后不会立即执行,而是在后续某个时机触发的场景。


总的来说,方案一(DI容器+工厂)是最优选择,它既解决了依赖传递的问题,又保持了代码的可维护性和可测试性。静态类虽然简单,但后续维护和测试会踩很多坑,尽量避免。

备注:内容来源于stack exchange,提问作者OlavT

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.04.23 14:37:29