diff --git a/packages/common/src/viewport_scroller.ts b/packages/common/src/viewport_scroller.ts index fad2a4e3af..0e57c942d9 100644 --- a/packages/common/src/viewport_scroller.ts +++ b/packages/common/src/viewport_scroller.ts @@ -22,6 +22,7 @@ export abstract class ViewportScroller { // See #23917 /** @nocollapse */ static ngInjectableDef = ɵɵdefineInjectable({ + token: ViewportScroller, providedIn: 'root', factory: () => new BrowserViewportScroller(ɵɵinject(DOCUMENT), window, ɵɵinject(ErrorHandler)) }); diff --git a/packages/core/src/change_detection/differs/iterable_differs.ts b/packages/core/src/change_detection/differs/iterable_differs.ts index 2d08ea8b5a..c80508eb6d 100644 --- a/packages/core/src/change_detection/differs/iterable_differs.ts +++ b/packages/core/src/change_detection/differs/iterable_differs.ts @@ -144,6 +144,7 @@ export interface IterableDifferFactory { export class IterableDiffers { /** @nocollapse */ static ngInjectableDef = ɵɵdefineInjectable({ + token: IterableDiffers, providedIn: 'root', factory: () => new IterableDiffers([new DefaultIterableDifferFactory()]) }); diff --git a/packages/core/src/change_detection/differs/keyvalue_differs.ts b/packages/core/src/change_detection/differs/keyvalue_differs.ts index 5c9571ef05..83c11b2ed8 100644 --- a/packages/core/src/change_detection/differs/keyvalue_differs.ts +++ b/packages/core/src/change_detection/differs/keyvalue_differs.ts @@ -119,6 +119,7 @@ export interface KeyValueDifferFactory { export class KeyValueDiffers { /** @nocollapse */ static ngInjectableDef = ɵɵdefineInjectable({ + token: KeyValueDiffers, providedIn: 'root', factory: () => new KeyValueDiffers([new DefaultKeyValueDifferFactory()]) }); diff --git a/packages/core/src/di/injectable.ts b/packages/core/src/di/injectable.ts index d64dfb9281..eb6fd4782b 100644 --- a/packages/core/src/di/injectable.ts +++ b/packages/core/src/di/injectable.ts @@ -90,6 +90,7 @@ function render2CompileInjectable( options: {providedIn?: Type| 'root' | null} & InjectableProvider): void { if (options && options.providedIn !== undefined && !getInjectableDef(injectableType)) { injectableType.ngInjectableDef = ɵɵdefineInjectable({ + token: injectableType, providedIn: options.providedIn, factory: convertInjectableProviderToFactory(injectableType, options), }); diff --git a/packages/core/src/di/injection_token.ts b/packages/core/src/di/injection_token.ts index ac16ca838a..f93c31f36e 100644 --- a/packages/core/src/di/injection_token.ts +++ b/packages/core/src/di/injection_token.ts @@ -68,6 +68,7 @@ export class InjectionToken { (this as any).__NG_ELEMENT_ID__ = options; } else if (options !== undefined) { this.ngInjectableDef = ɵɵdefineInjectable({ + token: this, providedIn: options.providedIn || 'root', factory: options.factory, }); diff --git a/packages/core/src/di/injector.ts b/packages/core/src/di/injector.ts index cd6556c18e..cecd9cf15b 100644 --- a/packages/core/src/di/injector.ts +++ b/packages/core/src/di/injector.ts @@ -89,6 +89,7 @@ export abstract class Injector { /** @nocollapse */ static ngInjectableDef = ɵɵdefineInjectable({ + token: Injector, providedIn: 'any' as any, factory: () => ɵɵinject(INJECTOR), }); diff --git a/packages/core/src/di/interface/defs.ts b/packages/core/src/di/interface/defs.ts index e92f931825..724dcb2c5b 100644 --- a/packages/core/src/di/interface/defs.ts +++ b/packages/core/src/di/interface/defs.ts @@ -37,6 +37,13 @@ export interface ɵɵInjectableDef { */ providedIn: InjectorType|'root'|'any'|null; + /** + * The token to which this definition belongs. + * + * Note that this may not be the same as the type that the `factory` will create. + */ + token: unknown; + /** * Factory method to execute to create an instance of the injectable. */ @@ -132,11 +139,13 @@ export interface InjectorTypeWithProviders { * @codeGenApi */ export function ɵɵdefineInjectable(opts: { + token: unknown, providedIn?: Type| 'root' | 'any' | null, factory: () => T, }): never { return ({ - providedIn: opts.providedIn as any || null, factory: opts.factory, value: undefined, + token: opts.token, providedIn: opts.providedIn as any || null, factory: opts.factory, + value: undefined, } as ɵɵInjectableDef) as never; } diff --git a/packages/core/src/render3/definition.ts b/packages/core/src/render3/definition.ts index ed07f6a001..287654bbf9 100644 --- a/packages/core/src/render3/definition.ts +++ b/packages/core/src/render3/definition.ts @@ -307,7 +307,7 @@ export function ɵɵdefineComponent(componentDefinition: { // be retrieved through the node injector, so this isn't a problem. if (!type.hasOwnProperty(NG_INJECTABLE_DEF)) { (type as any)[NG_INJECTABLE_DEF] = - ɵɵdefineInjectable({factory: componentDefinition.factory as() => T}); + ɵɵdefineInjectable({token: type, factory: componentDefinition.factory as() => T}); } }) as never; diff --git a/packages/core/test/bundling/injection/usage.ts b/packages/core/test/bundling/injection/usage.ts index 8f4c9a1f5b..ec7f6ae7c6 100644 --- a/packages/core/test/bundling/injection/usage.ts +++ b/packages/core/test/bundling/injection/usage.ts @@ -10,6 +10,7 @@ import {Injector, ɵcreateInjector as createInjector, ɵɵdefineInjectable, ɵɵ export class RootService { static ngInjectableDef = ɵɵdefineInjectable({ + token: RootService, providedIn: 'root', factory: () => new RootService(), }); @@ -17,6 +18,7 @@ export class RootService { export class ScopedService { static ngInjectableDef = ɵɵdefineInjectable({ + token: ScopedService, providedIn: null, factory: () => new ScopedService(), }); diff --git a/packages/core/test/di/r3_injector_spec.ts b/packages/core/test/di/r3_injector_spec.ts index f60301a0f2..4307985b59 100644 --- a/packages/core/test/di/r3_injector_spec.ts +++ b/packages/core/test/di/r3_injector_spec.ts @@ -13,6 +13,7 @@ import {expect} from '@angular/platform-browser/testing/src/matchers'; describe('InjectorDef-based createInjector()', () => { class CircularA { static ngInjectableDef = ɵɵdefineInjectable({ + token: CircularA, providedIn: null, factory: () => ɵɵinject(CircularB), }); @@ -20,6 +21,7 @@ describe('InjectorDef-based createInjector()', () => { class CircularB { static ngInjectableDef = ɵɵdefineInjectable({ + token: CircularB, providedIn: null, factory: () => ɵɵinject(CircularA), }); @@ -27,6 +29,7 @@ describe('InjectorDef-based createInjector()', () => { class Service { static ngInjectableDef = ɵɵdefineInjectable({ + token: Service, providedIn: null, factory: () => new Service(), }); @@ -34,6 +37,7 @@ describe('InjectorDef-based createInjector()', () => { class OptionalService { static ngInjectableDef = ɵɵdefineInjectable({ + token: OptionalService, providedIn: null, factory: () => new OptionalService(), }); @@ -56,6 +60,7 @@ describe('InjectorDef-based createInjector()', () => { constructor(readonly service: Service) {} static ngInjectableDef = ɵɵdefineInjectable({ + token: ServiceWithDep, providedIn: null, factory: () => new ServiceWithDep(ɵɵinject(Service)), }); @@ -65,6 +70,7 @@ describe('InjectorDef-based createInjector()', () => { constructor(@Optional() readonly service: OptionalService|null) {} static ngInjectableDef = ɵɵdefineInjectable({ + token: ServiceWithOptionalDep, providedIn: null, factory: () => new ServiceWithOptionalDep(ɵɵinject(OptionalService, InjectFlags.Optional)), }); @@ -74,6 +80,7 @@ describe('InjectorDef-based createInjector()', () => { constructor(readonly service: Service) {} static ngInjectableDef = ɵɵdefineInjectable({ + token: ServiceWithMissingDep, providedIn: null, factory: () => new ServiceWithMissingDep(ɵɵinject(Service)), }); @@ -83,6 +90,7 @@ describe('InjectorDef-based createInjector()', () => { constructor(readonly locale: string[]) {} static ngInjectableDef = ɵɵdefineInjectable({ + token: ServiceWithMultiDep, providedIn: null, factory: () => new ServiceWithMultiDep(ɵɵinject(LOCALE)), }); @@ -90,6 +98,7 @@ describe('InjectorDef-based createInjector()', () => { class ServiceTwo { static ngInjectableDef = ɵɵdefineInjectable({ + token: ServiceTwo, providedIn: null, factory: () => new ServiceTwo(), }); @@ -98,6 +107,7 @@ describe('InjectorDef-based createInjector()', () => { let deepServiceDestroyed = false; class DeepService { static ngInjectableDef = ɵɵdefineInjectable({ + token: DeepService, providedIn: null, factory: () => new DeepService(), }); @@ -108,6 +118,7 @@ describe('InjectorDef-based createInjector()', () => { let eagerServiceCreated: boolean = false; class EagerService { static ngInjectableDef = ɵɵdefineInjectable({ + token: EagerService, providedIn: undefined, factory: () => new EagerService(), }); @@ -203,6 +214,7 @@ describe('InjectorDef-based createInjector()', () => { let scopedServiceDestroyed = false; class ScopedService { static ngInjectableDef = ɵɵdefineInjectable({ + token: ScopedService, providedIn: Module, factory: () => new ScopedService(), }); @@ -212,6 +224,7 @@ describe('InjectorDef-based createInjector()', () => { class WrongScopeService { static ngInjectableDef = ɵɵdefineInjectable({ + token: WrongScopeService, providedIn: OtherModule, factory: () => new WrongScopeService(), }); diff --git a/packages/core/test/linker/ng_module_integration_spec.ts b/packages/core/test/linker/ng_module_integration_spec.ts index ee6eee8241..73ebe235f4 100644 --- a/packages/core/test/linker/ng_module_integration_spec.ts +++ b/packages/core/test/linker/ng_module_integration_spec.ts @@ -1397,6 +1397,7 @@ function declareTests(config?: {useJit: boolean}) { class Bar { static ngInjectableDef: ɵɵInjectableDef = ɵɵdefineInjectable({ + token: Bar, factory: () => new Bar(), providedIn: SomeModule, }); @@ -1429,6 +1430,7 @@ function declareTests(config?: {useJit: boolean}) { class Bar { static ngInjectableDef: ɵɵInjectableDef = ɵɵdefineInjectable({ + token: Bar, factory: () => new Bar(), providedIn: SomeModule, }); diff --git a/packages/core/test/render3/component_spec.ts b/packages/core/test/render3/component_spec.ts index 6526e39a43..97ee2c3690 100644 --- a/packages/core/test/render3/component_spec.ts +++ b/packages/core/test/render3/component_spec.ts @@ -63,8 +63,11 @@ describe('component', () => { class MyService { constructor(public value: string) {} - static ngInjectableDef = - ɵɵdefineInjectable({providedIn: 'root', factory: () => new MyService('no-injector')}); + static ngInjectableDef = ɵɵdefineInjectable({ + token: MyService, + providedIn: 'root', + factory: () => new MyService('no-injector'), + }); } class MyComponent { constructor(public myService: MyService) {} diff --git a/packages/core/test/render3/ivy/jit_spec.ts b/packages/core/test/render3/ivy/jit_spec.ts index cb976aec2a..d0bf5b9e44 100644 --- a/packages/core/test/render3/ivy/jit_spec.ts +++ b/packages/core/test/render3/ivy/jit_spec.ts @@ -168,6 +168,7 @@ ivyEnabled && describe('render3 jit', () => { it('compiles a module to an ngInjectorDef with the providers', () => { class Token { static ngInjectableDef = ɵɵdefineInjectable({ + token: Token, providedIn: 'root', factory: () => 'default', }); diff --git a/packages/core/test/render3/providers_spec.ts b/packages/core/test/render3/providers_spec.ts index 0e64029c90..241443a20d 100644 --- a/packages/core/test/render3/providers_spec.ts +++ b/packages/core/test/render3/providers_spec.ts @@ -58,8 +58,10 @@ describe('providers', () => { public greet: string; constructor(private provider: GreeterProvider) { this.greet = this.provider.provide(); } - static ngInjectableDef = - ɵɵdefineInjectable({factory: () => new GreeterInj(ɵɵinject(GreeterProvider as any))}); + static ngInjectableDef = ɵɵdefineInjectable({ + token: GreeterInj, + factory: () => new GreeterInj(ɵɵinject(GreeterProvider as any)), + }); } it('TypeProvider', () => { @@ -814,8 +816,11 @@ describe('providers', () => { it('should work with root', () => { @Injectable({providedIn: 'root'}) class FooForRoot { - static ngInjectableDef = - ɵɵdefineInjectable({factory: () => new FooForRoot(), providedIn: 'root'}); + static ngInjectableDef = ɵɵdefineInjectable({ + token: FooForRoot, + factory: () => new FooForRoot(), + providedIn: 'root', + }); } expectProvidersScenario({ @@ -836,8 +841,11 @@ describe('providers', () => { @Injectable({providedIn: MyModule}) class FooForModule { - static ngInjectableDef = - ɵɵdefineInjectable({factory: () => new FooForModule(), providedIn: MyModule}); + static ngInjectableDef = ɵɵdefineInjectable({ + token: FooForModule, + factory: () => new FooForModule(), + providedIn: MyModule, + }); } expectProvidersScenario({ @@ -1153,8 +1161,10 @@ describe('providers', () => { class MyService { constructor(public value: String) {} - static ngInjectableDef = - ɵɵdefineInjectable({factory: () => new MyService(ɵɵinject(String))}); + static ngInjectableDef = ɵɵdefineInjectable({ + token: MyService, + factory: () => new MyService(ɵɵinject(String)), + }); } expectProvidersScenario({ @@ -1171,7 +1181,10 @@ describe('providers', () => { it('should make sure that parent service does not see overrides in child directives', () => { class Greeter { - static ngInjectableDef = ɵɵdefineInjectable({factory: () => new Greeter(ɵɵinject(String))}); + static ngInjectableDef = ɵɵdefineInjectable({ + token: Greeter, + factory: () => new Greeter(ɵɵinject(String)), + }); constructor(public greeting: String) {} } @@ -1213,7 +1226,10 @@ describe('providers', () => { class SomeInj implements Some { constructor(public location: String) {} - static ngInjectableDef = ɵɵdefineInjectable({factory: () => new SomeInj(ɵɵinject(String))}); + static ngInjectableDef = ɵɵdefineInjectable({ + token: SomeInj, + factory: () => new SomeInj(ɵɵinject(String)), + }); } @Component({ diff --git a/packages/core/test/view/ng_module_spec.ts b/packages/core/test/view/ng_module_spec.ts index ec81d5c0ed..f6b75a8920 100644 --- a/packages/core/test/view/ng_module_spec.ts +++ b/packages/core/test/view/ng_module_spec.ts @@ -28,6 +28,7 @@ class NotMyModule {} class Bar { static ngInjectableDef: ɵɵInjectableDef = ɵɵdefineInjectable({ + token: Bar, factory: () => new Bar(), providedIn: MyModule, }); @@ -35,6 +36,7 @@ class Bar { class Baz { static ngInjectableDef: ɵɵInjectableDef = ɵɵdefineInjectable({ + token: Baz, factory: () => new Baz(), providedIn: NotMyModule, }); @@ -44,6 +46,7 @@ class HasNormalDep { constructor(public foo: Foo) {} static ngInjectableDef: ɵɵInjectableDef = ɵɵdefineInjectable({ + token: HasNormalDep, factory: () => new HasNormalDep(inject(Foo)), providedIn: MyModule, }); @@ -53,6 +56,7 @@ class HasDefinedDep { constructor(public bar: Bar) {} static ngInjectableDef: ɵɵInjectableDef = ɵɵdefineInjectable({ + token: HasDefinedDep, factory: () => new HasDefinedDep(inject(Bar)), providedIn: MyModule, }); @@ -62,6 +66,7 @@ class HasOptionalDep { constructor(public baz: Baz|null) {} static ngInjectableDef: ɵɵInjectableDef = ɵɵdefineInjectable({ + token: HasOptionalDep, factory: () => new HasOptionalDep(inject(Baz, InjectFlags.Optional)), providedIn: MyModule, }); @@ -69,6 +74,7 @@ class HasOptionalDep { class ChildDep { static ngInjectableDef: ɵɵInjectableDef = ɵɵdefineInjectable({ + token: ChildDep, factory: () => new ChildDep(), providedIn: MyChildModule, }); @@ -77,6 +83,7 @@ class ChildDep { class FromChildWithOptionalDep { constructor(public baz: Baz|null) {} static ngInjectableDef: ɵɵInjectableDef = ɵɵdefineInjectable({ + token: FromChildWithOptionalDep, factory: () => new FromChildWithOptionalDep(inject(Baz, InjectFlags.Default)), providedIn: MyChildModule, }); @@ -87,6 +94,7 @@ class FromChildWithSkipSelfDep { public skipSelfChildDep: ChildDep|null, public selfChildDep: ChildDep|null, public optionalSelfBar: Bar|null) {} static ngInjectableDef: ɵɵInjectableDef = ɵɵdefineInjectable({ + token: FromChildWithSkipSelfDep, factory: () => new FromChildWithSkipSelfDep( inject(ChildDep, InjectFlags.SkipSelf|InjectFlags.Optional), inject(ChildDep, InjectFlags.Self), @@ -210,6 +218,7 @@ describe('NgModuleRef_ injector', () => { ngOnDestroy(): void { Service.destroyed++; } static ngInjectableDef: ɵɵInjectableDef = ɵɵdefineInjectable({ + token: Service, factory: () => new Service(), providedIn: 'root', }); diff --git a/tools/public_api_guard/core/core.d.ts b/tools/public_api_guard/core/core.d.ts index ef6757b785..92c4521d98 100644 --- a/tools/public_api_guard/core/core.d.ts +++ b/tools/public_api_guard/core/core.d.ts @@ -778,6 +778,7 @@ export declare const ɵɵdefineDirective: (directiveDefinition: { }) => never; export declare function ɵɵdefineInjectable(opts: { + token: unknown; providedIn?: Type | 'root' | 'any' | null; factory: () => T; }): never; @@ -869,6 +870,7 @@ export declare function ɵɵinject(token: Type | InjectionToken, flags? export interface ɵɵInjectableDef { factory: () => T; providedIn: InjectorType | 'root' | 'any' | null; + token: unknown; value: T | undefined; }