请稍等 ...
×

采纳答案成功!

向帮助你的同学说点啥吧!感谢那些助人为乐的人

IOC 反转控制容器,保留同时实现不同时间段价格计算的理解,不知对否

老师你好
纯接口思路
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);
        }
        // 其他业务逻辑....
    }
}
1 回复 有任何疑惑可以回复我~
  • 提问者 六拉克 #1
    谢谢老师
    通过本身 xxxController 这个类的 Action() 方法,里面实现了 双十一价格计算和普通价格计算的逻辑封装,这样就在 最外部调用时,不含逻辑判断了,只关注向IOC容器注册和调用方式的处理。
    回复 有任何疑惑可以回复我~ 2023-01-11 10:41:47
  • 提问者 六拉克 #2
    谢谢老师
    通过在 class xxxController 类里面 Action() 封装 不同的价格计算,让外面使用时,只关注IOC容器本身的注册
    回复 有任何疑惑可以回复我~ 2023-01-11 10:48:25
问题已解决,确定采纳
还有疑问,暂不采纳
意见反馈 帮助中心 APP下载
官方微信