为什么不使用IoC容器来解析实体/业务对象的依赖关系?

Cas*_*ins 77 entities dependency-injection castle-windsor ioc-container inversion-of-control

我理解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);
    }
}
Run Code Online (Sandbox Code Playgroud)

如您所见,依赖项是Constructor Injected.现在提出几个问题.

  1. 让您的实体依赖于诸如ShipQuoter之类的外部类别是否被视为不良做法?如果我正确理解定义,消除这些依赖性似乎会导致我陷入贫血领域.

  2. 使用IoC容器来解决这些依赖关系并在需要时构建实体是不好的做法吗?是否有可能做到这一点?

感谢您的任何见解.

Mar*_*ann 87

第一个问题是最难回答的问题.让实体依赖外部课程是不好的做法吗?这当然不是最常见的事情.

例如,如果您将Repository注入实体,则实际上您可以实现Active Record模式.有些人喜欢这种模式,因为它提供了方便,而其他人(像我一样)认为它是代码嗅觉或反模式,因为它违反了单一责任原则(SRP).

您可以争辩说,将其他依赖项注入实体会使您处于同一方向(远离SRP).另一方面,你肯定是正确的,如果你不这样做,拉动就是一个贫血领域模型.

很长一段时间我一直在努力解决所有这些问题,直到我遇到关于DDDD的 Greg Young(已放弃)论文,他解释了为什么陈规定型的n层/ n层架构将始终是CRUDy(因此相当贫乏).

将我们的重点转移到将对象建模为命令和事件而不是名词似乎使我们能够构建适当的面向对象的域模型.

第二个问题更容易回答.您始终可以使用抽象工厂在运行时创建实例.使用Castle Windsor,您甚至可以使用Typed Factory Facility,从而减轻您手动实施工厂的负担.

  • 您与Greg论文的链接已经死亡.但它仍然可以[这里](http://web.archive.org/web/20130124235446/http://abdullin.com/storage/uploads/2010/04/2010-04-16_DDDD_Drafts_by_Greg_Young.pdf).它似乎[this](https://cqrs.files.wordpress.com/2010/11/cqrs_documents.pdf)是一个较新的版本. (4认同)