2

表达这个问题的一种与框架无关的方式是“如何使用服务定位器注册另一个服务?”

Injector 被设置为不可变的,无论是接口还是实现。

interface Injector {
    abstract get(token: any, notFoundValue?: any): any;
}

接口https://github.com/angular/angular/blob/master/packages/core/src/di/injector.ts 实现https://github.com/angular/angular/blob/master/packages/core/src /di/reflective_injector.ts

你如何添加另一个提供者(动态地,而不是通过模块)?

当 Angular 在引导后加载新模块时(例如通过路由器),它自己是如何做到这一点的?

4

1 回答 1

4

为了向现有注入器添加提供程序,您必须通过创建新注入器并传递父注入器来扩展它:

class Comp {
   constructor(existing: Injector) {
      const newInjector = ReflectiveInjector.resolveAndCreate(providers, existing)
   }
}

要获取更多详细信息,请阅读反射式注射器和 Angular 中的注射器之间的区别

当 Angular 在引导后加载新模块时(例如通过路由器),它自己是如何做到这一点的?

它使用了一些不同的机制。当创建一个新的模块实例时,它会传递给父注入器:

class NgModuleRef_ implements NgModuleData, InternalNgModuleRef<any> {    
  constructor(..., public _parent: Injector) {
    initNgModule(this);
  }

然后,当您请求令牌时,如果在现有注入器上找不到它,它会使用此父注入器来解决依赖关系:

NgModuleRef_.get(token, notFoundValue = Injector.THROW_IF_NOT_FOUND) {
     return resolveNgModuleDep(...);
}

export function resolveNgModuleDep(...) {
  ...
  if (found) return instance;
  return data._parent.get(depDef.token, notFoundValue);  <----------------
}
于 2017-08-03T09:14:42.343 回答