我理解 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);
}
}
如您所见,依赖项是构造函数注入(inject)的。现在有几个问题。
让您的实体依赖于外部类(例如 ShipQuoter)是否被认为是不好的做法?如果我正确理解了定义,消除这些依赖性似乎会让我走向贫血领域。
使用 IoC 容器来解决这些依赖关系并在需要时构造实体是一种不好的做法吗?可以这样做吗?
感谢您的见解。
最佳答案
第一个问题是最难回答的。让实体依赖外部类是不好的做法吗?这当然不是最常见的事情。
例如,如果您将存储库注入(inject)到您的实体中,您实际上就拥有了Active Record pattern的实现。 。有些人喜欢这种模式,因为它提供了便利,而另一些人(比如我)则认为它是一种代码味道或反模式,因为它违反了 Single Responsibility Principle (建议零售价)。
您可能会争辩说,将其他依赖项注入(inject)到实体中会将您拉向相同的方向(远离 SRP)。另一方面,你肯定是正确的,如果你不这样做,那么拉力就会朝向 Anemic Domain Model 。 .
我在这一切上挣扎了很长一段时间,直到我遇到了 Greg Young 的(废弃的)paper on DDDD他在其中解释了为什么典型的 n 层/n 层架构将始终是 CRUDy(因此相当贫乏)。
将我们的注意力转移到将领域对象建模为命令和事件而不是名词,似乎使我们能够构建适当的面向对象的领域模型。
第二个问题比较容易回答。您始终可以使用Abstract Factory to create instances at run-time 。通过 CaSTLe Windsor,您甚至可以使用类型化工厂设施,从而减轻您手动实现工厂的负担。
关于dependency-injection - 为什么不使用 IoC 容器来解决实体/业务对象的依赖关系?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/4835046/