我计划深入挖掘其中一个开源IoC容器,以便100%真正解决这个问题,但我想我也会问一般社区(在任何密切相关的问题中找不到直接答案之后) )。
据我了解典型的IoC实现,似乎它是一个全局类,充当了一个具有所有依赖性知识的单例。然后它使用该知识提供构造函数或属性参数,它知道如何填充它们?也许我错过了什么,所以问题。
有人可以明确地告诉我IoC是如何工作的和/或它是否是一个单身的根源?
更新
我想我的问题是怎么做"魔法" IoC的工作就像Ninject.MVC一样?注射的地方"只是工作"?
答案 0 :(得分:1)
IoC容器往往不是单例,因为可能希望同时运行多个容器(例如,每层系统一个),尽管这不是最常见的做法
为了访问您的容器,您需要引用实际容器本身。
即使您的容器不是真正的单例,您也可以使用服务定位器来访问它(请参阅http://msdn.microsoft.com/en-us/library/ff921142(v=pandp.20).aspx)。
答案 1 :(得分:1)
所有主要的DI框架(或至少在Java和.NET中)通常建议在应用程序的生命周期内拥有单个容器实例。有些容器确实支持'子容器'的概念,但那些子容器是从该单个容器创建的,实际上只是同一个实例的一部分。
绝对有可能拥有多个容器,例如每层或每个会话一个容器,但是当您根据依赖注入原则设计应用程序时,通常每个应用程序有一个容器(在.NET的上下文,这将是每个App域,或者通常是在同一个memort空间中运行的所有代码。处理由(桌面)客户端和Web服务组成的应用程序时,两者都有自己的容器(因为它们实际上是不同的程序,不知道另一个)。
虽然可以为每个(Web用户)会话,请求或类似的东西定义容器实例,但这往往会使事情复杂化,因为很难注册具有比会话更长的生命周期的依赖项,并且在创建容器时会产生很多性能开销。
答案 2 :(得分:0)
没有理由认为它应该是单身人士。仅仅因为你的实体通过上下文连接在一起,你仍然可以运行多个上下文(使用Spring白话,但不限制Spring的参数)
请注意,像Java这样的平台甚至不能强制执行单例(由于它们的多种类加载器架构)。
答案 3 :(得分:0)
好的,在进一步在线浏览并与同事交谈之后,我相信没有办法实现IoC(至少在有状态的程序...... winforms / wpf中),而不是静态单例。所以,我打算使用Composition Root模式,并使用ninject内核作为Service Locator方式的静态单例。我仍然会调用kernel.Get,但我想我至少会失去对该项中依赖项的关注。我只是在圈子里跑自己:)。
这样的事情:
Main
{
setupkernel();
Application.Run(kernel.Get<Main>);
}
btn_GetChildForm()
{
kernel.Get<ChildForm>().Show();
}
如果有人知道更好的方法,请告诉我。否则,这就是我拼凑起来作为最好的方法。
答案 4 :(得分:-1)
Service Locator is an Anti-Pattern
尝试并理解'组合根'的本质。