39

我有两个相关(与这个问题)项目和其他几个项目的解决方案;

  1. 具有其他几个项目使用的功能的类库。
  2. ASP.NET MVC 应用程序。

我的问题基本上是我应该在哪里用 Ninject 2 做 IoC,考虑到......

  • 类库需要一些 DI 的爱,其中包括需要 Web 请求特定会话对象的存储库类(想想工作单元)。
  • MVC 应用程序需要 DI,因为使用 Ninject 2,您基本上是从 NinjectHttpApplication 继承的。
  • 类库的单元测试需要意识到这一点才能注入一组不同的存储库。
  • 出于同样的原因,需要注入 Web 应用程序的单元测试。

我在这里把自己描绘成一个心理角落,因为我一开始只看到了三个选项。类库中的 DI,Web 应用程序中的 DI,或两者都有,但每个都有问题:

  • 我不能在类库中进行 DI,因为 MVC 应用程序首先需要从 NinjectHttpApplication 继承。
  • 我不能只在 MVC 应用程序中进行 DI - 毕竟,其他库使用类库,而且 MVC 应用程序不应该对库的内部了解太多。
  • 我想这是我能看到的唯一出路:两个项目的独立 IoC。类库和 MVC 应用程序都有自己的 IoC 设置,并为他们的东西做 DI,而不是真正关心彼此。

有没有人有一些关于如何做这样的事情的“最佳实践”或指导方针?我无法想象我是第一个遇到这种情况的人,很高兴知道这样做的“正确”方法是什么......

谢谢!

4

1 回答 1

64

我不知道 NInject,但除非它的工作方式与 Windsor、StructureMap 等有很大不同。答案往往保持不变,因为有一些常见的 DI 模式。考虑到这一点:

首先要意识到的是,DI 并不依赖于特定的框架,例如 NInject 或 Windsor。它是一组要遵循的技术和设计模式。您可以使用所谓的 Poor Man's DI 手动执行 DI,但显然使用 DI Container 会变得更好。

为什么这是相关的?这是相关的,因为一旦你意识到这一点,推论就是你的应用程序的绝大多数代码都不应该知道DI 容器什么的。

那么你在哪里使用 DI 容器呢?它只能在Composition Root中使用,在您的情况下,它对应于 Global.asax。您可以在这个 SO 答案中阅读更多相关信息- 尽管该问题是关于温莎的,但原理保持不变。

那么你的单元测试呢?他们也应该完全不知道 DI Container。有关更多详细信息,请参阅this other SO answer

DI can be achieved in your library with copious use of Constructor Injection. You don't need to reference any DI Container to do that, but it makes life a lot easier if you use a DI Container to resolve all dependencies from the Composition Root.

于 2009-09-25T07:15:43.120 回答