IOC 反转控制容器,保留同时实现不同时间段价格计算的理解,不知对否
来源:6-8 【操作】反转控制与依赖注入

六拉克
2023-01-09
老师你好
纯接口思路
ICalculate putong = new ShippingCalculator();// 普通时间段计算运费类
ICalculate doubleEleven = new DoubleElevenShippingCalculator();//双十一时间段计算运费类
OrderProcessor orderProcessor;
//模拟今天日期是否是双十一的比较
if (DateTime.Now.Month == new DateTime(2023, 11, 11).Month && DateTime.Now.Day == new DateTime(2023, 11, 11).Day)
{
orderProcessor = new OrderProcessor(doubleEleven);
}
else
{
orderProcessor = new OrderProcessor(putong);
}
orderProcessor.Process(order);
以上是没有使用 IOC 反转控制容器 的,通过 一个日期比较,实例化不同 价格计算器对象。
// 配置 IOC 反转控制容器
var collection = new ServiceCollection();
collection.AddScoped<IOrderProcessor, OrderProcessor>();
//模拟今天日期是否是双十一的比较
if (DateTime.Now.Month == new DateTime(2023, 11, 11).Month && DateTime.Now.Day == new DateTime(2023, 11, 11).Day)
{
collection.AddScoped<ICalculate, DoubleElevenShippingCalculator>();
}
else
{
collection.AddScoped<ICalculate, ShippingCalculator>();
}
IServiceProvider serviceProvider = collection.BuildServiceProvider();
var orderProcessor = serviceProvider.GetService();
// 处理订单
orderProcessor.Process(order);
这段是模仿老师,使用 IOC 反转控制容器
我目前有点困惑的地方是,如果要实现不改代码情况下,是不是 也要加个 if 条件判断(通过时间比较后),注册不同的价格计算器到容器中。像这段
if (DateTime.Now.Month == new DateTime(2023, 11, 11).Month && DateTime.Now.Day == new DateTime(2023, 11, 11).Day)
{
collection.AddScoped<ICalculate, DoubleElevenShippingCalculator>();
}
else
{
collection.AddScoped<ICalculate, ShippingCalculator>();
}
这样经过时间比较判断后,后面调用的时候,出现不同计算。因为例子只有一个价格容器计算,我想保留2种都能针对不同情况的价格计算,这样改造运行和上面一样,实现了不同时间段的价格计算,但自己心里没底,不知是不是这样的思路。
1回答
-
实际上IOC不仅可以注册单一的实现,它也同样可以注册接口的多重实现。所以,我们并不需要通过if...else...来按需注册,只需要把所有的实现全部丢进IOC就好了。
// 配置 IOC 反转控制容器 var collection = new ServiceCollection(); collection.AddScoped<IOrderProcessor, OrderProcessor>(); collection.AddScoped<ICalculate, DoubleElevenShippingCalculator>(); collection.AddScoped<ICalculate, ShippingCalculator>();
而在controler使用的时候,我们需要提取的是ICalculate服务列表而不是单独的ICalculate。使用操作符“is”,我们可以在if...else...通过对比类型来获得对应的计算服务。
public class xxxController { private readonly IEnumerable<ICalculate> _calculators; public xxxController(IEnumerable<ICalculate> calculators) { _calculators = calculators; } public void Action() { ICalculate calculator; if (DateTime.Now.Month == new DateTime(2023, 11, 11).Month && DateTime.Now.Day == new DateTime(2023, 11, 11).Day) { calculator = _calculators.FirstOrDefault(c => c is DoubleElevenShippingCalculator); } else { calculator = _calculators.FirstOrDefault(c => c is ShippingCalculator); } // 其他业务逻辑.... } }
122023-01-11
相似问题