“它只不过是一个奇特的对象哈希表。 ”
虽然上面的说法是一种轻描淡写的说法,但这是思考它们的简单方法。给定集合,如果您请求类的相同实例 - DI 容器将决定是否为您提供缓存版本或新版本,等等。
当涉及到连接依赖项时,它们的使用使得它变得更容易和更清晰。假设您有以下伪类。
class House(Kitchen, Bedroom)
// Use kitchen and bedroom.
end
class Kitchen()
// Code...
end
class Bedroom()
// Code...
end
Run Code Online (Sandbox Code Playgroud)
如果没有 DI 容器,建造房子会很痛苦,您需要创建一个卧室的实例,然后创建一个厨房的实例。如果这些对象也具有依赖关系,则需要将它们连接起来。反过来,您可能会花费许多行代码来连接对象。只有这样你才能建造一座有效的房子。使用 DI/IOC(控制反转)容器,您说想要一个房屋对象,DI 容器将递归地创建其每个依赖项并返回一个房屋。
没有 DI/IOC 容器:
house = new House(new Kitchen(), new Bedroom());
Run Code Online (Sandbox Code Playgroud)
使用 DI/IOC 容器:
house = // some method of getting the house
Run Code Online (Sandbox Code Playgroud)
最终,它们使代码更易于理解、更易于编写,并将将对象连接在一起的责任从手头的问题转移开。
DI Container的核心是根据接口和具体类型之间的映射创建对象.
这将允许您从容器中请求抽象类型:
IFoo f = container.Resolve<IFoo>();
Run Code Online (Sandbox Code Playgroud)
这要求您先前已将容器配置为从IFoo映射到实现IFoo的具体类(例如Foo).
这本身并不会特别令人印象深刻,但DI Containers做得更多:
一旦你开始尝试手动管理组合和生命周期,你应该开始欣赏DI容器提供的服务:)
许多DI容器可以做到比上面更多,但那些是核心服务.大多数容器提供通过代码或XML进行配置的选项.
在正确使用容器方面,Krzysztof Kozmic刚刚发表了一篇很好的概述.