2017-08-03 3 views
1

Un moyen agnostique de formuler cette question est "Comment enregistrer un autre service avec le localisateur de service?"Comment ajouter un autre fournisseur à l'injecteur?

L'Injecteur est configuré pour être immuable, à la fois l'interface et l'implémentation.

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

Interface https://github.com/angular/angular/blob/master/packages/core/src/di/injector.ts mise en œuvre https://github.com/angular/angular/blob/master/packages/core/src/di/reflective_injector.ts

Comment ajouter un autre fournisseur (dynamique, et non par l'intermédiaire d'un module)?

Comment Angular procède-t-il lui-même lors du chargement de nouveaux modules après l'amorçage, par exemple via le routeur?

Répondre

2

Pour ajouter un fournisseur à l'injecteur existant, vous devez l'étendre en créant un nouvel injecteur et l'injecteur passe parent:

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

Pour obtenir plus de détails lire Difference between Reflective Injector and Injector in Angular.

Comment Angular procède-t-il lui-même lors du chargement de nouveaux modules après , par exemple via le routeur?

Il utilise un mécanisme légèrement différent. Quand une nouvelle instance de module est créé, il est passé l'injecteur mère:

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

Et puis lorsque vous demandez un jeton qu'il utilise cet injecteur mère pour résoudre la dépendance si elle ne le trouve pas sur l'injecteur existant:

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

Intéressant. Il semble que cela a 2 conséquences: (1) Vous ne pouvez pas ajouter d'injectable à un module après qu'il a été amorcé (2) vous ne pouvez pas demander un injectable d'un module enfant dans le module parent. Parce que son existence n'est pas connue de l'injecteur parent. –

+0

@ErikvanVelzen, oui, c'est absolument correct –

+0

@ErikvanVelzen, y a-t-il quelque chose d'autre qui ne soit pas clair sur ma réponse? –