feat: allow direct scoping of @Injectables to the root injector (#22185)
@Injectable() supports a scope parameter which specifies the target module. However, it's still difficult to specify that a particular service belongs in the root injector. A developer attempting to ensure that must either also provide a module intended for placement in the root injector or target a module known to already be in the root injector (e.g. BrowserModule). Both of these strategies are cumbersome and brittle. Instead, this commit adds a token APP_ROOT_SCOPE which provides a straightforward way of targeting the root injector directly, without requiring special knowledge of modules within it. PR Close #22185
This commit is contained in:

committed by
Victor Berchet

parent
029dbf0e18
commit
7ac34e42a0
@ -8,6 +8,7 @@
|
||||
|
||||
import {resolveForwardRef} from '../di/forward_ref';
|
||||
import {InjectFlags, Injector, setCurrentInjector} from '../di/injector';
|
||||
import {APP_ROOT_SCOPE} from '../di/scope';
|
||||
import {NgModuleRef} from '../linker/ng_module_factory';
|
||||
import {stringify} from '../util';
|
||||
|
||||
@ -43,8 +44,12 @@ export function moduleProvideDef(
|
||||
export function moduleDef(providers: NgModuleProviderDef[]): NgModuleDefinition {
|
||||
const providersByKey: {[key: string]: NgModuleProviderDef} = {};
|
||||
const modules = [];
|
||||
let isRoot: boolean = false;
|
||||
for (let i = 0; i < providers.length; i++) {
|
||||
const provider = providers[i];
|
||||
if (provider.token === APP_ROOT_SCOPE) {
|
||||
isRoot = true;
|
||||
}
|
||||
if (provider.flags & NodeFlags.TypeNgModule) {
|
||||
modules.push(provider.token);
|
||||
}
|
||||
@ -57,6 +62,7 @@ export function moduleDef(providers: NgModuleProviderDef[]): NgModuleDefinition
|
||||
providersByKey,
|
||||
providers,
|
||||
modules,
|
||||
isRoot,
|
||||
};
|
||||
}
|
||||
|
||||
@ -119,8 +125,13 @@ export function resolveNgModuleDep(
|
||||
return data._parent.get(depDef.token, notFoundValue);
|
||||
}
|
||||
|
||||
function moduleTransitivelyPresent(ngModule: NgModuleData, scope: any): boolean {
|
||||
return ngModule._def.modules.indexOf(scope) > -1;
|
||||
}
|
||||
|
||||
function targetsModule(ngModule: NgModuleData, def: InjectableDef): boolean {
|
||||
return def.scope != null && ngModule._def.modules.indexOf(def.scope) > -1;
|
||||
return def.scope != null && (moduleTransitivelyPresent(ngModule, def.scope) ||
|
||||
def.scope === APP_ROOT_SCOPE && ngModule._def.isRoot);
|
||||
}
|
||||
|
||||
function _createProviderInstance(ngModule: NgModuleData, providerDef: NgModuleProviderDef): any {
|
||||
|
@ -43,6 +43,7 @@ export interface NgModuleDefinition extends Definition<NgModuleDefinitionFactory
|
||||
providers: NgModuleProviderDef[];
|
||||
providersByKey: {[tokenKey: string]: NgModuleProviderDef};
|
||||
modules: any[];
|
||||
isRoot: boolean;
|
||||
}
|
||||
|
||||
export interface NgModuleDefinitionFactory extends DefinitionFactory<NgModuleDefinition> {}
|
||||
|
Reference in New Issue
Block a user