Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

refactor(core): make any injector scope configurable #54907

Open
wants to merge 1 commit into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
3 changes: 2 additions & 1 deletion packages/core/src/application/create_application.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ import {createOrReusePlatformInjector} from '../platform/platform';
import {PLATFORM_DESTROY_LISTENERS} from '../platform/platform_ref';
import {assertStandaloneComponentType} from '../render3/errors';
import {setLocaleId} from '../render3/i18n/i18n_locale_id';
import {EnvironmentNgModuleRefAdapter} from '../render3/ng_module_ref';
import {EnvironmentNgModuleRefAdapter, getDefaultEnvironmentScope} from '../render3/ng_module_ref';
import {NgZone} from '../zone/ng_zone';

import {ApplicationInitStatus} from './application_init';
Expand Down Expand Up @@ -66,6 +66,7 @@ export function internalCreateApplication(config: {
// We skip environment initializers because we need to run them inside the NgZone, which
// happens after we get the NgZone instance from the Injector.
runEnvironmentInitializers: false,
scopes: getDefaultEnvironmentScope(),
});
const envInjector = adapter.injector;
const ngZone = envInjector.get(NgZone);
Expand Down
8 changes: 4 additions & 4 deletions packages/core/src/di/create_injector.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,8 +21,8 @@ import {InjectorScope} from './scope';
export function createInjector(
defType: /* InjectorType<any> */ any, parent: Injector|null = null,
additionalProviders: Array<Provider|StaticProvider>|null = null, name?: string): Injector {
const injector =
createInjectorWithoutInjectorInstances(defType, parent, additionalProviders, name);
const injector = createInjectorWithoutInjectorInstances(
defType, parent, additionalProviders, new Set(['any']), name);
injector.resolveInjectorInitializers();
return injector;
}
Expand All @@ -34,8 +34,8 @@ export function createInjector(
*/
export function createInjectorWithoutInjectorInstances(
defType: /* InjectorType<any> */ any, parent: Injector|null = null,
additionalProviders: Array<Provider|StaticProvider>|null = null, name?: string,
scopes = new Set<InjectorScope>()): R3Injector {
additionalProviders: Array<Provider|StaticProvider>|null = null, scopes: Set<InjectorScope>,
name?: string): R3Injector {
const providers = [
additionalProviders || EMPTY_ARRAY,
importProvidersFrom(defType),
Expand Down
2 changes: 1 addition & 1 deletion packages/core/src/di/r3_injector.ts
Original file line number Diff line number Diff line change
Expand Up @@ -455,7 +455,7 @@ export class R3Injector extends EnvironmentInjector {
}
const providedIn = resolveForwardRef(def.providedIn);
if (typeof providedIn === 'string') {
return providedIn === 'any' || (this.scopes.has(providedIn));
return this.scopes.has(providedIn);
} else {
return this.injectorDefTypes.has(providedIn);
}
Expand Down
2 changes: 1 addition & 1 deletion packages/core/src/di/scope.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
import {InjectionToken} from './injection_token';


export type InjectorScope = 'root'|'platform'|'environment';
export type InjectorScope = 'root'|'platform'|'environment'|'any';

/**
* An internal token whose presence in an injector indicates that the injector should treat itself
Expand Down
22 changes: 18 additions & 4 deletions packages/core/src/render3/ng_module_ref.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import {createInjectorWithoutInjectorInstances} from '../di/create_injector';
import {Injector} from '../di/injector';
import {EnvironmentProviders, Provider, StaticProvider} from '../di/interface/provider';
import {EnvironmentInjector, getNullInjector, R3Injector} from '../di/r3_injector';
import {InjectorScope} from '../di/scope';
import {Type} from '../interface/type';
import {ComponentFactoryResolver as viewEngine_ComponentFactoryResolver} from '../linker/component_factory_resolver';
import {InternalNgModuleRef, NgModuleFactory as viewEngine_NgModuleFactory, NgModuleRef as viewEngine_NgModuleRef} from '../linker/ng_module_factory';
Expand Down Expand Up @@ -78,7 +79,7 @@ export class NgModuleRef<T> extends viewEngine_NgModuleRef<T> implements Interna
},
...additionalProviders
],
stringify(ngModuleType), new Set(['environment'])) as R3Injector;
getDefaultEnvironmentScope(), stringify(ngModuleType)) as R3Injector;

// We need to resolve the injector types separately from the injector creation, because
// the module might be trying to use this ref in its constructor for DI which will cause a
Expand Down Expand Up @@ -120,6 +121,10 @@ export function createNgModuleRefWithProviders<T>(
return new NgModuleRef(moduleType, parentInjector, additionalProviders);
}

export function getDefaultEnvironmentScope() {
return new Set<InjectorScope>(['environment', 'any']);
}

export class EnvironmentNgModuleRefAdapter extends viewEngine_NgModuleRef<null> {
override readonly injector: R3Injector;
override readonly componentFactoryResolver: ComponentFactoryResolver =
Expand All @@ -130,7 +135,8 @@ export class EnvironmentNgModuleRefAdapter extends viewEngine_NgModuleRef<null>
providers: Array<Provider|EnvironmentProviders>,
parent: EnvironmentInjector|null,
debugName: string|null,
runEnvironmentInitializers: boolean
runEnvironmentInitializers: boolean,
scopes: Set<InjectorScope>,
}) {
super();
const injector = new R3Injector(
Expand All @@ -139,7 +145,7 @@ export class EnvironmentNgModuleRefAdapter extends viewEngine_NgModuleRef<null>
{provide: viewEngine_NgModuleRef, useValue: this},
{provide: viewEngine_ComponentFactoryResolver, useValue: this.componentFactoryResolver},
],
config.parent || getNullInjector(), config.debugName, new Set(['environment']));
config.parent || getNullInjector(), config.debugName, config.scopes);
this.injector = injector;
if (config.runEnvironmentInitializers) {
injector.resolveInjectorInitializers();
Expand Down Expand Up @@ -171,7 +177,15 @@ export class EnvironmentNgModuleRefAdapter extends viewEngine_NgModuleRef<null>
export function createEnvironmentInjector(
providers: Array<Provider|EnvironmentProviders>, parent: EnvironmentInjector,
debugName: string|null = null): EnvironmentInjector {
const scopes = getDefaultEnvironmentScope();
return createEnvironmentInjectorWithScope(providers, parent, scopes, debugName);
}

/** Internal function to create an environment injector with specified scopes. */
export function createEnvironmentInjectorWithScope(
providers: Array<Provider|EnvironmentProviders>, parent: EnvironmentInjector,
scopes: Set<InjectorScope>, debugName: string|null = null): EnvironmentInjector {
const adapter = new EnvironmentNgModuleRefAdapter(
{providers, parent, debugName, runEnvironmentInitializers: true});
{providers, parent, debugName, scopes, runEnvironmentInitializers: true});
return adapter.injector;
}
31 changes: 30 additions & 1 deletion packages/core/test/acceptance/di_spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2412,7 +2412,7 @@ describe('di', () => {
});

describe('Tree shakable injectors', () => {
it('should support tree shakable injectors scopes', () => {
it('`Injector.create` should support tree shakable injectors scopes', () => {
@Injectable({providedIn: 'any'})
class AnyService {
constructor(public injector: Injector) {}
Expand Down Expand Up @@ -2441,6 +2441,35 @@ describe('di', () => {
expect(platformService.injector.get(ɵINJECTOR_SCOPE)).toBe('platform');
});

it('`createEnvironmentInjector` should support tree shakable injectors scopes', () => {
@Injectable({providedIn: 'any'})
class AnyService {
constructor(public injector: Injector) {}
}

@Injectable({providedIn: 'root'})
class RootService {
constructor(public injector: Injector) {}
}

@Injectable({providedIn: 'platform'})
class PlatformService {
constructor(public injector: Injector) {}
}

const testBedInjector: Injector = TestBed.get(Injector);
const childInjector = createEnvironmentInjector([], testBedInjector as EnvironmentInjector);

const anyService = childInjector.get(AnyService);
expect(anyService.injector).toBe(childInjector);

const rootService = childInjector.get(RootService);
expect(rootService.injector.get(ɵINJECTOR_SCOPE)).toBe('root');

const platformService = childInjector.get(PlatformService);
expect(platformService.injector.get(ɵINJECTOR_SCOPE)).toBe('platform');
});

it('should create a provider that uses `forwardRef` inside `providedIn`', () => {
@Injectable()
class ProviderDep {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -905,6 +905,9 @@
{
"name": "getDeclarationTNode"
},
{
"name": "getDefaultEnvironmentScope"
},
{
"name": "getDirectiveDef"
},
Expand Down
3 changes: 3 additions & 0 deletions packages/core/test/bundling/defer/bundle.golden_symbols.json
Original file line number Diff line number Diff line change
Expand Up @@ -842,6 +842,9 @@
{
"name": "getDeclarationTNode"
},
{
"name": "getDefaultEnvironmentScope"
},
{
"name": "getDeferBlockDataIndex"
},
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -803,6 +803,9 @@
{
"name": "getDeclarationTNode"
},
{
"name": "getDefaultEnvironmentScope"
},
{
"name": "getDirectiveDef"
},
Expand Down
3 changes: 3 additions & 0 deletions packages/core/test/bundling/router/bundle.golden_symbols.json
Original file line number Diff line number Diff line change
Expand Up @@ -1268,6 +1268,9 @@
{
"name": "getDeclarationTNode"
},
{
"name": "getDefaultEnvironmentScope"
},
{
"name": "getDirectiveDef"
},
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -659,6 +659,9 @@
{
"name": "getDeclarationTNode"
},
{
"name": "getDefaultEnvironmentScope"
},
{
"name": "getDirectiveDef"
},
Expand Down