3

我有一个具有以下项目的解决方案:

  • 核心(包含用于处理的类,与业务对象/域无关)
  • 域(包含业务对象)
  • 线束(控制台应用程序)
  • MVC4 应用程序
  • 持久性(包含存储库接口、EF 映射等的实现)
  • 存储库(包含存储库接口)
  • 测试(包含单元测试)

我想使用 NInject 作为我的 IoC 容器,因为我有使用它的经验,但是我愿意接受更适合我需求的建议。

域对象需要了解存储库,以便他们可以进行数据访问(即,Person 类可能想要检索所有 AddressDetails)。一切都被编码为接口,以帮助单元测试中的模拟。

我不希望域项目依赖于 IoC 容器,但我需要某种方式让域项目中创建的所有实例都注入正确的存储库。我怎样才能做到这一点?我还希望能够在必要时从线束和测试项目中进行注入。我能想到的唯一方法是在 Domain 类中有一个静态对象,该对象包装来自 NInject 的 StandardKernel 并调用它来填充依赖项。如果我可以让构造函数注入工作,我认为它不会使用该方法,那也很好。我能想到的另一种选择是有一个工厂来构建具有正确依赖关系的域对象,但我宁愿能够拥有 IPerson person = new Person() 而不是每次都必须调用工厂。

提前致谢。

4

2 回答 2

3

域对象需要了解存储库,以便他们可以进行数据访问(即,Person 类可能想要检索所有 AddressDetails)。一切都被编码为接口,以帮助单元测试中的模拟。

域对象是内存中的对象和持久的无知,因此它不需要知道任何存储库。如果使用 ORM,AddressDetails 应该是延迟加载的,或者应该在 Person 实体之外分配。

因此,通过这种方式,无需将域实体放入 IoC 容器中。请注意,不要过度使用IoC Container,考虑一下应该放入哪些类型。如果所有东西都放入 IoC Container 中,那将是杂乱无章的类型池。

应该放入 IoC 的适当类是每一层的主要类,例如:

  1. 服务。
  2. 存储库。
  3. 甲骨文。
  4. 控制器。
  5. 横切关注点:日志、缓存...

不应放入其他内存中的类。

于 2012-08-25T08:25:03.410 回答
1

听起来您应该将Composition Root引入 MVC4 项目和控制台应用程序。因此,所有依赖项将仅在整个生产代码中耦合。您也可以定义自己的实现StandardKernel,或使用自动发现来查找所有实现。

有两个示例如何实现composition root 重载StandartKernel自动发现ninject.web.mvc这可能是有用的起点。Composition root对于控制台应用程序通常有简单的实现。

对于测试项目,您可以使用ninject.mockingkernel适当的模拟库,或者自己构建所有依赖项。对于纯单元测试,第二个选项应该很明显,但对于集成测试,第一个更合适。

领域对象的注入

  • 首先有几种众所周知的注入方法:

    • 通过构造函数,
    • 财产,
    • 方法
    • 语境。

    例如,只为域对象实现一个非默认构造函数,它定义了该对象的所有必需依赖项。如果它依赖于存储库,请在域对象的构造函数中指定它,并且没有其他方法可以创建这个特定的域对象而不指定它。

  • 其次,这样做可以避免对任何依赖注入库的依赖
于 2012-08-25T09:25:50.947 回答