diff --git a/packages/core/src/application_init.ts b/packages/core/src/application_init.ts index 554c120d9d..3c5f6ae3b0 100644 --- a/packages/core/src/application_init.ts +++ b/packages/core/src/application_init.ts @@ -8,7 +8,9 @@ import {isPromise} from '../src/util/lang'; -import {Inject, Injectable, InjectionToken, Optional} from './di'; +import {Inject, Injectable, InjectionToken, Optional, inject} from './di'; +import {defineInjectable} from './di/defs'; + /** @@ -22,8 +24,22 @@ export const APP_INITIALIZER = new InjectionToken void>>('Applicatio * * @experimental */ -@Injectable() export class ApplicationInitStatus { + // `ngInjectableDef` is required in core-level code because it sits behind + // the injector and any code the loads it inside may run into a dependency + // loop (because Injectable is also in core. Do not use the code below + // (use @Injectable({ providedIn, factory })) instead... + /** + * @internal + * @nocollapse + */ + static ngInjectableDef = defineInjectable({ + providedIn: 'root', + factory: function ApplicationInitStatus_Factory() { + return new ApplicationInitStatus(inject(APP_INITIALIZER)); + } + }); + private resolve: Function; private reject: Function; private initialized = false; diff --git a/packages/core/src/application_module.ts b/packages/core/src/application_module.ts index affd64c99c..2ba332383c 100644 --- a/packages/core/src/application_module.ts +++ b/packages/core/src/application_module.ts @@ -6,13 +6,11 @@ * found in the LICENSE file at https://angular.io/license */ -import {ApplicationInitStatus} from './application_init'; -import {ApplicationRef} from './application_ref'; import {APP_ID_RANDOM_PROVIDER} from './application_tokens'; import {IterableDiffers, KeyValueDiffers, defaultIterableDiffers, defaultKeyValueDiffers} from './change_detection/change_detection'; import {Inject, Optional, SkipSelf} from './di/metadata'; +import {APP_ROOT} from './di/scope'; import {LOCALE_ID} from './i18n/tokens'; -import {Compiler} from './linker/compiler'; import {NgModule} from './metadata'; export function _iterableDiffersFactory() { @@ -28,17 +26,14 @@ export function _localeFactory(locale?: string): string { } /** - * This module includes the providers of @angular/core that are needed - * to bootstrap components via `ApplicationRef`. - * * @experimental */ @NgModule({ providers: [ - ApplicationRef, - ApplicationInitStatus, - Compiler, APP_ID_RANDOM_PROVIDER, + // wen-workers need this value to be here since WorkerApp is defined + // ontop of this application + {provide: APP_ROOT, useValue: true}, {provide: IterableDiffers, useFactory: _iterableDiffersFactory}, {provide: KeyValueDiffers, useFactory: _keyValueDiffersFactory}, { @@ -49,6 +44,4 @@ export function _localeFactory(locale?: string): string { ] }) export class ApplicationModule { - // Inject ApplicationRef to make it eager... - constructor(appRef: ApplicationRef) {} } diff --git a/packages/core/src/application_ref.ts b/packages/core/src/application_ref.ts index ce30069931..e1de29f1f5 100644 --- a/packages/core/src/application_ref.ts +++ b/packages/core/src/application_ref.ts @@ -16,7 +16,8 @@ import {isPromise} from '../src/util/lang'; import {ApplicationInitStatus} from './application_init'; import {APP_BOOTSTRAP_LISTENER, PLATFORM_INITIALIZER} from './application_tokens'; import {Console} from './console'; -import {Injectable, InjectionToken, Injector, StaticProvider} from './di'; +import {Injectable, InjectionToken, Injector, StaticProvider, inject} from './di'; +import {defineInjectable} from './di/defs'; import {CompilerFactory, CompilerOptions} from './linker/compiler'; import {ComponentFactory, ComponentRef} from './linker/component_factory'; import {ComponentFactoryBoundToModule, ComponentFactoryResolver} from './linker/component_factory_resolver'; @@ -361,8 +362,26 @@ function optionsReducer(dst: any, objs: T | T[]): T { * * */ -@Injectable() export class ApplicationRef { + // `ngInjectableDef` is required in core-level code because it sits behind + // the injector and any code the loads it inside may run into a dependency + // loop (because Injectable is also in core. Do not use the code below + // (use @Injectable({ providedIn, factory })) instead... + /** + * @internal + * @nocollapse + */ + static ngInjectableDef = defineInjectable({ + providedIn: 'root', + factory: function ApplicationRef_Factory() { + // Type as any is used here due to a type-related bug in injector with abstract classes + // (#23528) + return new ApplicationRef( + inject(NgZone), inject(Console), inject(Injector as any), inject(ErrorHandler), + inject(ComponentFactoryResolver as any), inject(ApplicationInitStatus)); + } + }); + /** @internal */ static _tickScope: WtfScopeFn = wtfCreateScope('ApplicationRef#tick()'); private _bootstrapListeners: ((compRef: ComponentRef) => void)[] = []; diff --git a/packages/core/src/linker/compiler.ts b/packages/core/src/linker/compiler.ts index d9e5acec94..ba0283657b 100644 --- a/packages/core/src/linker/compiler.ts +++ b/packages/core/src/linker/compiler.ts @@ -6,7 +6,8 @@ * found in the LICENSE file at https://angular.io/license */ -import {Injectable, InjectionToken, StaticProvider} from '../di'; +import {Injectable, InjectionToken, StaticProvider, inject} from '../di'; +import {defineInjectable} from '../di/defs'; import {MissingTranslationStrategy} from '../i18n/tokens'; import {ViewEncapsulation} from '../metadata'; import {Type} from '../type'; @@ -15,6 +16,7 @@ import {ComponentFactory} from './component_factory'; import {NgModuleFactory} from './ng_module_factory'; + /** * Combination of NgModuleFactory and ComponentFactorys. * @@ -41,8 +43,17 @@ function _throwError() { * of components. * */ -@Injectable() export class Compiler { + // `ngInjectableDef` is required in core-level code because it sits behind + // the injector and any code the loads it inside may run into a dependency + // loop (because Injectable is also in core. Do not use the code below + // (use @Injectable({ providedIn, factory })) instead... + /** + * @internal + * @nocollapse + */ + static ngInjectableDef = defineInjectable({providedIn: 'root', factory: () => new Compiler()}); + /** * Compiles the given NgModule and all of its components. All templates of the components listed * in `entryComponents` have to be inlined. diff --git a/packages/core/test/bundling/hello_world_r2/bundle.golden_symbols.json b/packages/core/test/bundling/hello_world_r2/bundle.golden_symbols.json index 1c925c3984..a739f151c0 100644 --- a/packages/core/test/bundling/hello_world_r2/bundle.golden_symbols.json +++ b/packages/core/test/bundling/hello_world_r2/bundle.golden_symbols.json @@ -188,6 +188,9 @@ { "name": "APP_BOOTSTRAP_LISTENER" }, + { + "name": "APP_INITIALIZER" + }, { "name": "APP_ROOT" }, diff --git a/packages/platform-server/src/styles_host.ts b/packages/platform-server/src/styles_host.ts index fa19f0faeb..531ea3db3a 100644 --- a/packages/platform-server/src/styles_host.ts +++ b/packages/platform-server/src/styles_host.ts @@ -6,7 +6,7 @@ * found in the LICENSE file at https://angular.io/license */ -import {ApplicationRef, Inject, Injectable, Optional} from '@angular/core'; +import {Inject, Injectable, Optional} from '@angular/core'; import {DOCUMENT, ɵDomAdapter as DomAdapter, ɵSharedStylesHost as SharedStylesHost, ɵTRANSITION_ID, ɵgetDOM as getDOM} from '@angular/platform-browser'; @Injectable() diff --git a/packages/upgrade/test/common/downgrade_component_adapter_spec.ts b/packages/upgrade/test/common/downgrade_component_adapter_spec.ts index c428c24bd8..54c81478c4 100644 --- a/packages/upgrade/test/common/downgrade_component_adapter_spec.ts +++ b/packages/upgrade/test/common/downgrade_component_adapter_spec.ts @@ -5,7 +5,7 @@ * Use of this source code is governed by an MIT-style license that can be * found in the LICENSE file at https://angular.io/license */ -import {ApplicationRef, Compiler, Component, ComponentFactory, ComponentRef, Injector, NgModule, Testability, TestabilityRegistry} from '@angular/core'; +import {Compiler, Component, ComponentFactory, ComponentRef, Injector, NgModule, Testability, TestabilityRegistry} from '@angular/core'; import {TestBed, getTestBed, inject} from '@angular/core/testing'; import * as angular from '@angular/upgrade/src/common/angular1'; import {DowngradeComponentAdapter, groupNodesBySelector} from '@angular/upgrade/src/common/downgrade_component_adapter'; diff --git a/tools/public_api_guard/core/core.d.ts b/tools/public_api_guard/core/core.d.ts index d781017237..5730fd9d7c 100644 --- a/tools/public_api_guard/core/core.d.ts +++ b/tools/public_api_guard/core/core.d.ts @@ -35,7 +35,6 @@ export declare class ApplicationInitStatus { /** @experimental */ export declare class ApplicationModule { - constructor(appRef: ApplicationRef); } export declare class ApplicationRef {