我了解 DI 背后的概念,但我只是在学习不同的 IoC 容器可以做什么。似乎大多数人都主张使用 IoC 容器来连接无状态服务,但是将它们用于实体等有状态对象呢?
无论是对还是错,我通常都会用行为填充我的实体,即使该行为需要外部类。例子:
public class Order : IOrder
{
private string _ShipAddress;
private IShipQuoter _ShipQuoter;
public Order(IOrderData OrderData, IShipQuoter ShipQuoter)
{
// OrderData comes from a repository and has the data needed
// to construct order
_ShipAddress = OrderData.ShipAddress; // etc.
_ShipQuoter = ShipQuoter;
}
private decimal GetShippingRate()
{
return _ShipQuoter.GetRate(this);
}
}
如您所见,依赖项是构造函数注入的。现在有几个问题。
让您的实体依赖于外部类(例如 ShipQuoter)是否被认为是不好的做法?如果我正确理解了定义,消除这些依赖性似乎会让我走向贫血领域。
使用 IoC 容器来解决这些依赖关系并在需要时构建实体是一种不好的做法吗?是否有可能做到这一点?
感谢您的任何见解。
第一个问题是最难回答的。让实体依赖外部类是不好的做法吗?这当然不是最常见的事情。
例如,如果您将存储库注入到您的实体中,您实际上就拥有了活动记录模式。有些人喜欢这种模式是因为它提供了便利,而其他人(比如我)则认为它是一种代码味道或反模式,因为它违反了单一责任原则 (SRP).
您可能会争辩说,将其他依赖项注入实体会将您拉向相同的方向(远离 SRP)。另一方面,你肯定是正确的,如果你不这样做,那么吸引力就会转向贫血域模型.
我与这一切斗争了很长一段时间,直到我遇到了格雷格·杨(Greg Young)(已废弃)关于 DDDD 的论文他解释了原因刻板的 n 层/n 层架构将始终是 CRUDy(因此相当贫血)。
将我们的重点转移到对领域对象进行建模命令和事件而不是名词似乎使我们能够构建适当的面向对象的领域模型。
第二个问题更容易回答。您始终可以使用抽象工厂在运行时创建实例。通过 Castle Windsor,您甚至可以使用类型化工厂设施,从而减轻您手动实施工厂的负担。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)