2017-08-03 26 views
1

这个问题的框架不可知的方式是“如何使用服务定位器注册另一个服务?”如何添加另一个供应商到注射器?

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在自举之后如何在加载新模块时进行此操作,例如通过路由器?

回答

2

为了提供者添加到您必须通过创建一个新的注射器把它扩大,并通过母公司注入现有的注射器:

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

如需更多信息阅读Difference between Reflective Injector and Injector in Angular

Angular在bootstrapping之后加载新模块时会如何执行此操作,例如通过路由器?

它使用了一点不同的机制。当创建一个新的模块,例如它通过了母公司注入:

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); <---------------- 
} 
+0

有趣。看起来这有两个后果:(1)在引导完成后,你不能将任何注射添加到模块中(2)你不能在父模块中请求注入子模块。因为它的存在并不知道父喷油器。 –

+0

@ErikvanVelzen,是的,这是绝对正确的 –

+0

@ErikvanVelzen,还有什么不清楚我的答案? –

相关问题