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

如何将现有代码改造为依赖注入模式?满足动态创建Condition需求

改造代码实现依赖注入并支持动态创建Condition

核心思路

  1. 引入条件工厂(Condition Factory),让ScheduleManager仅依赖工厂而非具体条件的依赖,避免构造函数参数膨胀。
  2. 利用DI容器自动注入Condition子类的依赖,每个Condition的依赖由自身构造函数声明,与ScheduleManager完全解耦。
  3. 通过JSON配置文件定义需要创建的Condition类型,工厂读取配置后从DI容器中动态获取实例。

改造后的完整代码

1. 新增配置模型与工厂类

using System.Text.Json;
using Microsoft.Extensions.DependencyInjection;

// JSON配置模型:定义每个Condition的类型信息
public class ConditionConfig
{
    public string TypeName { get; set; } = string.Empty;
}

// 条件工厂接口
public interface IConditionFactory
{
    List<Condition> CreateConditionsFromJson(string jsonPath);
}

// 条件工厂实现:负责读取JSON并动态创建Condition实例
public class ConditionFactory : IConditionFactory
{
    private readonly IServiceProvider _serviceProvider;

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

    public List<Condition> CreateConditionsFromJson(string jsonPath)
    {
        var jsonContent = File.ReadAllText(jsonPath);
        var configs = JsonSerializer.Deserialize<List<ConditionConfig>>(jsonContent) 
            ?? throw new InvalidOperationException("解析条件配置JSON失败");

        var conditions = new List<Condition>();
        foreach (var config in configs)
        {
            // 获取Condition类型(需使用完整命名空间+类名)
            var conditionType = Type.GetType(config.TypeName);
            if (conditionType == null || !typeof(Condition).IsAssignableFrom(conditionType))
            {
                throw new InvalidOperationException($"无效的条件类型: {config.TypeName}");
            }

            // 从DI容器获取Condition实例(自动注入其依赖)
            var condition = (Condition)_serviceProvider.GetRequiredService(conditionType);
            conditions.Add(condition);
        }

        return conditions;
    }
}

2. 改造ScheduleManager

public class ScheduleManager
{
    private readonly List<Condition> _conditions;

    // 仅依赖IConditionFactory,无需传递任何Condition的具体依赖
    public ScheduleManager(IConditionFactory conditionFactory)
    {
        // 读取JSON配置并创建Condition列表
        _conditions = conditionFactory.CreateConditionsFromJson("conditions.json");
    }

    // 示例方法:检查所有条件是否满足
    public bool AllConditionsMet()
    {
        return _conditions.All(c => c.IsTrue());
    }
}

3. 原基础类保持不变(接口与Condition子类)

namespace ConsoleApp3
{
    public interface IPriceList
    {
        double GetPrice();
    }

    public class PriceList : IPriceList
    {
        public double GetPrice() => 2.3;
    }

    public interface ISensorValue
    {
        double GetValue();
    }

    public class SensorValue : ISensorValue
    {
        public double GetValue() => 20.5;
    }

    public abstract class Condition
    {
        public abstract bool IsTrue();
    }

    public class PriceCondition : Condition
    {
        private readonly IPriceList _priceList;

        // 依赖通过构造函数注入,由DI容器自动解析
        public PriceCondition(IPriceList priceList)
        {
            _priceList = priceList;
        }

        public override bool IsTrue() => _priceList.GetPrice() > 4.4;
    }

    public class SensorCondition : Condition
    {
        private readonly ISensorValue _sensorValue;

        // 依赖通过构造函数注入,由DI容器自动解析
        public SensorCondition(ISensorValue sensorValue)
        {
            _sensorValue = sensorValue;
        }

        public override bool IsTrue() => _sensorValue.GetValue() > 20.4;
    }
}

4. 程序入口与DI容器配置

namespace ConsoleApp3
{
    internal class Program
    {
        static void Main(string[] args)
        {
            // 构建DI容器
            var services = new ServiceCollection();

            // 注册基础服务
            services.AddSingleton<IPriceList, PriceList>();
            services.AddSingleton<ISensorValue, SensorValue>();

            // 注册所有Condition类型(让DI容器能够解析它们)
            services.AddSingleton<PriceCondition>();
            services.AddSingleton<SensorCondition>();

            // 注册工厂与ScheduleManager
            services.AddSingleton<IConditionFactory, ConditionFactory>();
            services.AddSingleton<ScheduleManager>();

            // 构建服务提供者
            using var serviceProvider = services.BuildServiceProvider();

            // 获取ScheduleManager实例(DI自动注入所有依赖)
            var scheduleManager = serviceProvider.GetRequiredService<ScheduleManager>();

            // 测试输出
            Console.WriteLine($"所有条件是否满足:{scheduleManager.AllConditionsMet()}");
        }
    }
}

5. 配套的JSON配置文件(conditions.json)

[
    { "TypeName": "ConsoleApp3.PriceCondition" },
    { "TypeName": "ConsoleApp3.SensorCondition" }
]

关键说明

  • 解耦ScheduleManager:它不再需要关心各个Condition的依赖,仅通过工厂获取实例,彻底避免构造函数参数膨胀。
  • 动态创建:只需修改JSON配置,就能新增/移除Condition,无需改动ScheduleManager的代码。
  • 依赖注入自动解析:每个Condition的依赖(如IPriceList)由DI容器自动注入,符合依赖倒置原则。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.02 19:41:06