2

我计划深入研究其中一个开源 IoC 容器以真正 100% 解决这个问题,但我想我也会问一般社区(在无法在任何密切相关的问题中找到直接答案之后)。

据我了解典型的 IoC 实现,它似乎是一个全局类,充当具有所有依赖项知识的单例。然后它使用这些知识来提供构造函数或属性参数,它知道如何填充它们?也许我错过了一些东西,因此是这个问题。

有人可以明确地告诉我 IoC 是如何工作的和/或它是否是一个单例?

更新

我想我的问题是“神奇”的 IoC 是如何像 Ninject.MVC 一样工作的?注射在哪里“有效”?

4

5 回答 5

1

IoC 容器往往不是单例的,因为您可能希望同时运行多个容器(例如,系统的每层一个),尽管这不是最常见的做法。

为了访问您的容器,您需要对实际容器本身的引用。

即使您的容器不是真正的单例,您也可以使用服务定位器访问它(另请参阅http://msdn.microsoft.com/en-us/library/ff921142(v=pandp.20).aspx)。

于 2012-11-05T15:28:47.980 回答
1

所有主要的 DI 框架(或至少在 Java 和 .NET 中)通常建议在应用程序的生命周期内拥有单个容器实例。一些容器确实支持“子容器”的概念,但这些子容器是从单个容器创建的,实际上只是同一个实例的一部分。

绝对有可能拥有多个容器,例如每层或每个会话一个容器,但是当您根据依赖注入原则设计应用程序时,通常每个应用程序一个容器(在 . NET 这将是每个应用程序域,或者通常是在同一内存空间中运行的所有代码)。在处理由(桌面)客户端和 Web 服务组成的应用程序时,两者都有自己的容器(因为它们实际上是不同的程序,彼此不知道)。

尽管可以为每个(Web 用户)会话、请求或类似的东西定义一个容器实例,但这往往会使事情复杂化,因为很难注册比会话更长的生命周期的依赖项,而且有很多创建容器时的性能开销。

于 2012-11-05T17:21:17.710 回答
0

没有理由为什么它应该是一个单例。仅仅因为您通过上下文将实体连接在一起,您仍然可以运行多个上下文(使用 Spring 白话,但不将参数限制为 Spring)

请注意,像 Java 这样的平台甚至不能强制执行单例(由于它们的多类加载器架构)。

于 2012-11-05T15:32:13.110 回答
0

好的,在进一步在线浏览并与同事交谈之后,我相信没有静态单例就无法实现 IoC(至少在有状态程序中..winforms/wpf 中)。因此,我计划使用组合根模式,并以服务定位器的方式将 ninject 内核用作静态单例。我仍然会调用 kernel.Get,但我想我至少不再关心该项目中的依赖关系。我只是在兜圈子:)。

像这样的东西:

Main
{
  setupkernel();
  Application.Run(kernel.Get<Main>);
}

btn_GetChildForm()
{
    kernel.Get<ChildForm>().Show();
}

如果有人知道更好的方法,请告诉我。否则,这就是我拼凑起来的最佳方法。

于 2012-11-05T16:43:43.950 回答
-1

服务定位器是一种反模式

尝试并了解“组合根”的性质。

于 2012-11-07T12:13:02.443 回答