2009-06-22 40 views
2

我目前正在为我使用的程序编写一个开源SDK,并且我在内部使用一个IoC容器(NInject)来连接所有内部依赖项。在内部对象中使用IoC

我有一些标记为内部的对象,因此我不会挤占公共API,因为它们只在内部使用,不应该被用户看到,像工厂和其他对象。我遇到的问题是NInject无法创建内部对象,这意味着我必须将所有公开的内部对象标记为公共API。

我的问题是:有没有办法解决这个问题,还是我这样做都是错的?

PS。我曾考虑过使用InternalsVisiableTo属性,但我觉得这有点味道。

+0

如果它是一个开源的SDK,我想知道为什么你想阻止你的代码的使用?我明白如果你想确保我们的SDK“用户”不会错误地实例化对象,但对我来说,这更像是一种异味(SRP,LSP)。你能解释一下你的约束吗? – 2009-11-02 14:38:07

回答

3

快速浏览一下其他答案:它不”你看起来像是在做一些如此不同的事情,Ninject有一些根本性的错误,你需要修改或替换它。在许多情况下,你不能“直接去找内部”,因为它们依赖于未解决的依赖注入;因此首先使用Ninject。这听起来像你已经有一个内部的一组接口,这就是为什么提出的问题。

想法:直接在您的SDK或库中使用Ninject的一个问题是,那么您的用户将不得不在他们的代码中使用Ninject。这对你来说可能不是问题,因为它是你的IoC选择,所以你仍然要使用它。如果他们想要使用另一个IoC容器,那么现在他们实际上有两个正在运行的重复工作。更糟糕的是,如果他们想要使用Ninject v2并且你已经使用了v1.5,那么这会让情况变得非常复杂。

最好的情况:,如果你可以重构你的等级,所以他们得到他们通过依赖注入需要的,那么这是最干净的,因为库代码不需要任何 IoC容器的一切。该应用程序可以连接依赖关系,它只是流动。但这并不总是可能的,因为有时库类需要创建具有依赖性的实例,而这些依赖性无法通过注入来解决。

建议:CommonServiceLocator(和the Ninject adapter它)是专门为这种情况(与依赖库)设计。您针对CommonServiceLocator进行编码,然后应用程序指定哪个DI/IoC实际支持该接口。

现在,您必须在应用程序中使用Ninject CommonServiceLocator,但CommonServiceLocator非常轻便,这有点痛苦。您的SDK /库代码只有使用相当干净的CommonServiceLocator。

0

我想你甚至不需要那个。 IoC是为了公共资料。直接进入内部。

但是 - 这只是我的直觉......

0

创建二级,内部API,它是从外部API不同。你可能需要做手工分割...

-1

可以

  • 修改Ninject
  • 选择不同的容器
0

我打算为InternalsVisibleTo解决方案投票。完全没有气味,真的。这个属性的要点是启用你想要的行为,而不是跳过各种精心设计的环节,让事情没有它,只需使用框架提供的功能来解决这个特定的问题。

我也建议,如果你想隐藏你从用户容器的选择,使用ILMerge到Ninject组件与SDK组件相结合,并应用/内在参数改变Ninject组件的可见性到内部,因此Ninject命名空间不会泄漏出您的库(对不起,无法在线找到ILMerge文档的链接,但下载时有一个doc文件)。还有这个关于将ILMerge集成到构建过程中的nice blog post