gpt4 book ai didi

c# - IoC 和构造函数过度注入(inject)反模式解决方案

转载 作者:可可西里 更新时间:2023-11-01 08:57:56 25 4
gpt4 key购买 nike

这个问题是 Jeffery Palermo 关于如何绕过分支代码和依赖项注入(inject)的帖子的结果 http://jeffreypalermo.com/blog/constructor-over-injection-anti-pattern/

在他的帖子中,Jeffery 有一个类(public class OrderProcessor : IOrderProcessor)在构造函数上采用 2 个接口(interface)。一个是验证器 IOrderValidator 和一个 IOrderShipper 接口(interface)。他的方法代码在仅使用 IOrderValidator 接口(interface)上的方法之后出现分支,并且从未在 IOrderShipper 接口(interface)上使用任何东西。

他建议创建一个工厂,该工厂将调用静态方法来获取接口(interface)的委托(delegate)。他正在重构的代码中创建一个新对象,这似乎是不必要的。

我想问题的症结在于我们正在使用 IoC 来构建我们所有的对象,无论它们是否被使用。 如果您使用 2 个接口(interface)实例化一个对象,并且有可能分支到不使用其中一个接口(interface)的代码,您将如何处理它?<​​/strong>

在此示例中,我们假设 _validator.Validate(order) 始终返回 false 并且永远不会调用 IOrderShipper.Ship() 方法。

原始代码:

public class OrderProcessor : IOrderProcessor
{
private readonly IOrderValidator _validator;
private readonly IOrderShipper _shipper;

public OrderProcessor(IOrderValidator validator, IOrderShipper shipper)
{
_validator = validator;
_shipper = shipper;
}

public SuccessResult Process(Order order)
{
bool isValid = _validator.Validate(order);
if (isValid)
{
_shipper.Ship(order);
}
return CreateStatus(isValid);
}

private SuccessResult CreateStatus(bool isValid)
{
return isValid ? SuccessResult.Success : SuccessResult.Failed;
}
}

public class OrderShipper : IOrderShipper
{
public OrderShipper()
{
Thread.Sleep(TimeSpan.FromMilliseconds(777));
}

public void Ship(Order order)
{
//ship the order
}
}

重构代码

public class OrderProcessor : IOrderProcessor
{
private readonly IOrderValidator _validator;

public OrderProcessor(IOrderValidator validator)
{
_validator = validator;
}

public SuccessResult Process(Order order)
{
bool isValid = _validator.Validate(order);
if (isValid)
{
IOrderShipper shipper = new OrderShipperFactory().GetDefault();
shipper.Ship(order);
}
return CreateStatus(isValid);
}

private SuccessResult CreateStatus(bool isValid)
{
return isValid ? SuccessResult.Success : SuccessResult.Failed;
}
}

public class OrderShipperFactory
{
public static Func<IOrderShipper> CreationClosure;
public IOrderShipper GetDefault()
{
return CreationClosure(); //executes closure
}
}

下面是在启动时配置这个工厂的方法(ASP.NET 的 global.asax):

private static void ConfigureFactories()
{
OrderShipperFactory.CreationClosure =
() => ObjectFactory.GetInstance<IOrderShipper>();
}

最佳答案

我刚刚发布了一个rebuttal of Jeffrey Palermos post .

简而言之,我们不应该让具体的实现细节影响我们的设计。这将违反架构规模上的里氏替换原则。

一个更优雅的解决方案让我们通过引入延迟加载 OrderShipper 来保持设计。

关于c# - IoC 和构造函数过度注入(inject)反模式解决方案,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2103010/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com