如何将现有代码改造为依赖注入模式?满足动态创建Condition需求
改造代码实现依赖注入并支持动态创建Condition
核心思路
- 引入条件工厂(Condition Factory),让ScheduleManager仅依赖工厂而非具体条件的依赖,避免构造函数参数膨胀。
- 利用DI容器自动注入Condition子类的依赖,每个Condition的依赖由自身构造函数声明,与ScheduleManager完全解耦。
- 通过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
相关产品推荐
相关产品推荐

