【问题标题】:How to add another provider to the injector?如何向注入器添加另一个提供程序?
【发布时间】:2017-08-03 09:08:33
【问题描述】:

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

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 在引导后加载新模块时如何自己做这件事,例如通过路由器?

【问题讨论】:

    标签: angular dependency-injection angular-di


    【解决方案1】:

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

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

    如需了解更多详情,请阅读Difference between Reflective Injector and Injector in 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);  <----------------
    }
    

    【讨论】:

    • 有趣。似乎这有两个后果:(1)在引导模块后,您不能向模块添加任何可注入(2)您不能在父模块中请求子模块的可注入。因为父注入器不知道它的存在。
    猜你喜欢
    • 2012-09-04
    • 1970-01-01
    • 2016-07-26
    • 1970-01-01
    • 1970-01-01
    • 2019-04-04
    • 2020-08-14
    • 1970-01-01
    • 2017-12-09
    相关资源
    最近更新 更多