什么是 Container
Container 翻译为容器,又叫作依赖注入容器。
容器负责保存 token 和服务之间的绑定关系。当我们通过容器获取服务时,容器会自动帮我们实例化服务对象,并且自动完成初始化逻辑。
当我们多次获取同一个服务时,容器会返回同一个对象,因为容器只会在第一次获取服务时进行实例化和初始化逻辑,随后会把服务对象放入缓存,后续再次获取服务对象时,直接返回缓存中的服务对象。
Note
在 Angular 中,Container 被实现为 Injector,又叫作注入器。它们是同一个概念。
假如没有 Container
上面提到容器主要做了两件事,1 是绑定 token 和服务,2 是获取服务对象。
在没有容器这一概念的前提下,我们可能的一个实现方案如下:
ts
// 这里只是伪代码
// 通过全局方法bindService绑定token和服务工厂
bindService(token, someServiceFactory);
// 通过token获取服务对象
const service = getService(token);
可以看出来这两个 API 显得比较分散,不够内聚。更加关键的问题是这样的实现隐含着只能在全局维护一份 token 和服务之间的绑定关系。
相反通过 Container,可以让 API 更加内聚,而且我们可以实例化多个 container 对象,然后组合这些 container 对象形成一颗 container 树。从而支持分级注入的特性。
ts
// 这里只是伪代码
const parent = new Container();
const child = parent.createChild();
parent.bind('tokenA', ClassA);
child.bind('tokenB', ClassB);
// 注意到child容器中并没有定义tokenA,但是仍然可以获取到服务A
// 这是因为在child容器中没有找到tokenA,会继续到父级容器寻找,如果仍然没找到,就继续从父级容器中寻找,直到寻找到tokenA,或者父级容器不存在为止
const serviceA = child.get('tokenA');
// 这里会直接抛出异常,因为parent容器中没有tokenB,而且parent也没有父级容器。
const serviceB = parent.get('tokenB');