【发布时间】:2010-06-23 15:28:46
【问题描述】:
简单来说和/或在高级伪代码中,DI 容器如何工作以及如何使用它?
【问题讨论】:
标签: dependency-injection inversion-of-control
简单来说和/或在高级伪代码中,DI 容器如何工作以及如何使用它?
【问题讨论】:
标签: dependency-injection inversion-of-control
DI 容器的核心是基于接口和具体类型之间的映射创建对象。
这将允许您从容器中请求一个抽象类型:
IFoo f = container.Resolve<IFoo>();
这要求您之前配置容器以从 IFoo 映射到实现 IFoo 的具体类(例如 Foo)。
这本身不会特别令人印象深刻,但 DI Containers 做得更多:
一旦您开始尝试手动管理 composition 和 lifetimes,您应该开始欣赏 DI Container 提供的服务 :)
许多 DI 容器可以做的比上述更多,但这些是核心服务。大多数容器都提供configuring via either code or XML 的选项。
谈到容器的正确使用,Krzysztof Kozmic 刚刚发布了a good overview。
【讨论】:
"这不过是一个花哨的哈希 对象表。"
虽然上述内容是一种严重的轻描淡写,但这是考虑它们的简单方法。给定集合,如果您要求一个类的相同实例 - DI 容器将决定是给您一个缓存版本还是一个新版本,等等。
在连接依赖项时,它们的使用使连接变得更容易和更清晰。假设您有以下伪类。
class House(Kitchen, Bedroom)
// Use kitchen and bedroom.
end
class Kitchen()
// Code...
end
class Bedroom()
// Code...
end
如果没有 DI 容器,建造房子会很痛苦,您需要创建一个卧室实例,然后创建一个厨房实例。如果这些对象也有依赖关系,则需要将它们连接起来。反过来,您可以花费很多行代码来连接对象。只有这样你才能创建一个有效的房子。使用 DI/IOC(控制反转)容器你说你想要一个房子对象,DI 容器将递归地创建它的每个依赖项并返回给你一个房子。
没有 DI/IOC 容器:
house = new House(new Kitchen(), new Bedroom());
使用 DI/IOC 容器:
house = // some method of getting the house
归根结底,它们使代码更易于遵循、更易于编写,并将将对象连接在一起的责任从手头的问题上转移开。
【讨论】:
您配置一个 DI 容器,以便它了解您的接口和类型 - 每个接口如何映射到一个类型。
当您在其上调用Resolve 时,它会查看映射并返回您请求的映射对象。
一些 DI 容器使用约定而不是配置,例如,如果您定义一个接口 ISomething,它将寻找具体的 Something 类型来实例化并返回。
【讨论】: