DI容器如何工作的最简单解释?

时间:2010-06-22 19:15:14

标签: dependency-injection inversion-of-control

简单来说和/或高级伪代码,DI容器如何工作以及如何使用?

3 个答案:

答案 0 :(得分:5)

DI Container的核心是在接口和具体类型之间基于映射创建对象。

这将允许您从容器中请求抽象类型:

IFoo f = container.Resolve<IFoo>();

这要求您先前配置容器以从IFoo映射到实现IFoo的具体类(例如Foo)。

这本身并不会特别令人印象深刻,但DI容器会做得更多:

  • 他们使用自动接线这意味着他们可以自动判断如果IFoo映射到Foo并且IBar映射到Bar,但是Foo依赖于IBar,它将创建一个Foo实例请求IFoo时的栏。
  • 他们管理组件的生命周期。你们每次都想要一个新的Foo实例,但在其他情况下你可能需要相同的实例。您甚至可能每次都想要新的Foo实例,但注入的Bar应该保持相同的实例。

一旦您开始尝试手动管理合成生命周期,您应该开始欣赏DI Container提供的服务:)

许多DI容器可以做的远不止以上,但那些是核心服务。大多数容器都提供configuring via either code or XML的选项。

对于正确使用的容器,Krzysztof Kozmic刚刚发布了a good overview

答案 1 :(得分:4)

  

它只不过是花哨的哈希   对象表。

虽然以上是一个大规模的轻描淡写,但这是思考它们的简单方法。给定集合,如果你要求同一个类的实例 - DI容器将决定是给你一个缓存版本还是新版本,等等。

它们的使用使得在连接依赖关系时更容易和更清洁。想象一下,你有以下伪类。

class House(Kitchen, Bedroom)
     // Use kitchen and bedroom.
end

class Kitchen()
    // Code...
end

class Bedroom()
   // Code...
end

构建房屋是一个没有DI容器的痛苦,你需要创建一个卧室的实例,然后是一个厨房的实例。如果这些对象也具有依赖关系,则需要将它们连接起来。反过来,您可以花费很多代码来连接对象。只有这样你才能创建一个有效的房子。使用DI / IOC(Inversion of Control)容器,你说你想要一个house对象,DI容器将递归地创建它的每个依赖项并返回你的房子。

没有DI / IOC容器:

house = new House(new Kitchen(), new Bedroom());

使用DI / IOC容器:

house = // some method of getting the house

在一天结束时,他们使代码易于遵循,更容易编写,并将布线对象的责任转移到远离手头的问题。

答案 2 :(得分:2)

您配置DI容器,以便它知道您的接口和类型 - 每个接口如何映射到类型。

当你在上面调用Resolve时,它会查看映射并返回你请求的映射对象。

某些DI容器使用约定优于配置,例如,如果定义接口ISomething,它将查找具体的Something类型来实例化并返回。