refactor: use view engine also for NgModuleFactory
s (#16658)
* refactor(core): provide error message in stack for reflective DI Fixes #16355 * fix(compiler): make AOT work with `noUnusedParameters` Fixes #15532 * refactor: use view engine also for `NgModuleFactory`s This is a prerequisite for being able to mock providers in AOTed code later on.
This commit is contained in:
@ -54,8 +54,13 @@ export class CodegenComponentFactoryResolver implements ComponentFactoryResolver
|
||||
}
|
||||
|
||||
resolveComponentFactory<T>(component: {new (...args: any[]): T}): ComponentFactory<T> {
|
||||
let factory = this._factories.get(component) || this._parent.resolveComponentFactory(component);
|
||||
|
||||
let factory = this._factories.get(component);
|
||||
if (!factory && this._parent) {
|
||||
factory = this._parent.resolveComponentFactory(component);
|
||||
}
|
||||
if (!factory) {
|
||||
throw noComponentFactoryError(component);
|
||||
}
|
||||
return new ComponentFactoryBoundToModule(factory, this._ngModule);
|
||||
}
|
||||
}
|
||||
|
@ -6,12 +6,10 @@
|
||||
* found in the LICENSE file at https://angular.io/license
|
||||
*/
|
||||
|
||||
import {Injector, THROW_IF_NOT_FOUND} from '../di/injector';
|
||||
import {Injector} from '../di/injector';
|
||||
import {Type} from '../type';
|
||||
import {stringify} from '../util';
|
||||
|
||||
import {ComponentFactory} from './component_factory';
|
||||
import {CodegenComponentFactoryResolver, ComponentFactoryBoundToModule, ComponentFactoryResolver} from './component_factory_resolver';
|
||||
import {ComponentFactoryResolver} from './component_factory_resolver';
|
||||
|
||||
|
||||
/**
|
||||
@ -50,76 +48,16 @@ export abstract class NgModuleRef<T> {
|
||||
abstract onDestroy(callback: () => void): void;
|
||||
}
|
||||
|
||||
export interface InternalNgModuleRef<T> extends NgModuleRef<T> {
|
||||
// Note: we are using the prefix _ as NgModuleData is an NgModuleRef and therefore directly
|
||||
// exposed to the user.
|
||||
_bootstrapComponents: Type<any>[];
|
||||
}
|
||||
|
||||
/**
|
||||
* @experimental
|
||||
*/
|
||||
export class NgModuleFactory<T> {
|
||||
constructor(
|
||||
private _injectorClass: {new (parentInjector: Injector): NgModuleInjector<T>},
|
||||
private _moduleType: Type<T>) {}
|
||||
|
||||
get moduleType(): Type<T> { return this._moduleType; }
|
||||
|
||||
create(parentInjector: Injector|null): NgModuleRef<T> {
|
||||
const instance = new this._injectorClass(parentInjector || Injector.NULL);
|
||||
instance.create();
|
||||
return instance;
|
||||
}
|
||||
}
|
||||
|
||||
const _UNDEFINED = new Object();
|
||||
|
||||
export abstract class NgModuleInjector<T> implements Injector, NgModuleRef<T> {
|
||||
bootstrapFactories: ComponentFactory<any>[];
|
||||
instance: T;
|
||||
|
||||
private _destroyListeners: (() => void)[] = [];
|
||||
private _destroyed: boolean = false;
|
||||
private _cmpFactoryResolver: CodegenComponentFactoryResolver;
|
||||
|
||||
constructor(
|
||||
public parent: Injector, factories: ComponentFactory<any>[],
|
||||
bootstrapFactories: ComponentFactory<any>[]) {
|
||||
this.bootstrapFactories =
|
||||
bootstrapFactories.map(f => new ComponentFactoryBoundToModule(f, this));
|
||||
this._cmpFactoryResolver = new CodegenComponentFactoryResolver(
|
||||
factories, parent.get(ComponentFactoryResolver, ComponentFactoryResolver.NULL), this);
|
||||
}
|
||||
|
||||
create() { this.instance = this.createInternal(); }
|
||||
|
||||
abstract createInternal(): T;
|
||||
|
||||
get(token: any, notFoundValue: any = THROW_IF_NOT_FOUND): any {
|
||||
if (token === Injector || token === NgModuleRef) {
|
||||
return this;
|
||||
}
|
||||
|
||||
if (token === ComponentFactoryResolver) {
|
||||
return this._cmpFactoryResolver;
|
||||
}
|
||||
|
||||
const result = this.getInternal(token, _UNDEFINED);
|
||||
return result === _UNDEFINED ? this.parent.get(token, notFoundValue) : result;
|
||||
}
|
||||
|
||||
abstract getInternal(token: any, notFoundValue: any): any;
|
||||
|
||||
get injector(): Injector { return this; }
|
||||
|
||||
get componentFactoryResolver(): ComponentFactoryResolver { return this._cmpFactoryResolver; }
|
||||
|
||||
destroy(): void {
|
||||
if (this._destroyed) {
|
||||
throw new Error(
|
||||
`The ng module ${stringify(this.instance.constructor)} has already been destroyed.`);
|
||||
}
|
||||
this._destroyed = true;
|
||||
this.destroyInternal();
|
||||
this._destroyListeners.forEach((listener) => listener());
|
||||
}
|
||||
|
||||
onDestroy(callback: () => void): void { this._destroyListeners.push(callback); }
|
||||
|
||||
abstract destroyInternal(): void;
|
||||
export abstract class NgModuleFactory<T> {
|
||||
abstract get moduleType(): Type<T>;
|
||||
abstract create(parentInjector: Injector|null): NgModuleRef<T>;
|
||||
}
|
||||
|
Reference in New Issue
Block a user