feat(ivy): add support of ApplicationRef.bootstrapModuleFactory (#23811)

PR Close #23811
This commit is contained in:
Jason Aden
2018-05-09 16:49:39 -07:00
committed by Victor Berchet
parent 86b13ccf80
commit 22b58a717a
29 changed files with 580 additions and 153 deletions

View File

@ -32,6 +32,9 @@ export const INJECTOR = new InjectionToken<Injector>('INJECTOR');
export class NullInjector implements Injector {
get(token: any, notFoundValue: any = _THROW_IF_NOT_FOUND): any {
if (notFoundValue === _THROW_IF_NOT_FOUND) {
// Intentionally left behind: With dev tools open the debugger will stop here. There is no
// reason why correctly written application should cause this exception.
debugger;
throw new Error(`NullInjectorError: No provider for ${stringify(token)}!`);
}
return notFoundValue;
@ -487,11 +490,11 @@ export function injectArgs(types: (Type<any>| InjectionToken<any>| any[])[]): an
for (let j = 0; j < arg.length; j++) {
const meta = arg[j];
if (meta instanceof Optional || meta.__proto__.ngMetadataName === 'Optional') {
if (meta instanceof Optional || meta.ngMetadataName === 'Optional') {
flags |= InjectFlags.Optional;
} else if (meta instanceof SkipSelf || meta.__proto__.ngMetadataName === 'SkipSelf') {
} else if (meta instanceof SkipSelf || meta.ngMetadataName === 'SkipSelf') {
flags |= InjectFlags.SkipSelf;
} else if (meta instanceof Self || meta.__proto__.ngMetadataName === 'Self') {
} else if (meta instanceof Self || meta.ngMetadataName === 'Self') {
flags |= InjectFlags.Self;
} else if (meta instanceof Inject) {
type = meta.token;

View File

@ -151,10 +151,6 @@ export interface StaticClassProvider extends StaticClassSansProvider {
*
* For more details, see the {@linkDocs guide/dependency-injection "Dependency Injection Guide"}.
*
* ### Example
*
* {@example core/di/ts/provider_spec.ts region='ConstructorSansProvider'}
*
* @experimental
*/
export interface ConstructorSansProvider {
@ -453,5 +449,5 @@ export interface ClassProvider extends ClassSansProvider {
*
*
*/
export type Provider =
TypeProvider | ValueProvider | ClassProvider | ExistingProvider | FactoryProvider | any[];
export type Provider = TypeProvider | ValueProvider | ClassProvider | ConstructorProvider |
ExistingProvider | FactoryProvider | any[];

View File

@ -14,7 +14,7 @@ import {InjectableDef, InjectableType, InjectorDef, InjectorType, InjectorTypeWi
import {resolveForwardRef} from './forward_ref';
import {InjectableDefToken, InjectionToken} from './injection_token';
import {INJECTOR, InjectFlags, Injector, NullInjector, THROW_IF_NOT_FOUND, USE_VALUE, inject, injectArgs, setCurrentInjector} from './injector';
import {ClassProvider, ConstructorProvider, ExistingProvider, FactoryProvider, Provider, StaticClassProvider, TypeProvider, ValueProvider} from './provider';
import {ClassProvider, ConstructorProvider, ExistingProvider, FactoryProvider, Provider, StaticClassProvider, StaticProvider, TypeProvider, ValueProvider} from './provider';
import {APP_ROOT} from './scope';
@ -64,14 +64,15 @@ interface Record<T> {
}
/**
* Create a new `Injector` which is configured using `InjectorType`s.
* Create a new `Injector` which is configured using a `defType` of `InjectorType<any>`s.
*
* @experimental
*/
export function createInjector(
defType: /* InjectorType<any> */ any, parent: Injector | null = null): Injector {
defType: /* InjectorType<any> */ any, parent: Injector | null = null,
additionalProviders: StaticProvider[] | null = null): Injector {
parent = parent || getNullInjector();
return new R3Injector(defType, parent);
return new R3Injector(defType, additionalProviders, parent);
}
export class R3Injector {
@ -101,12 +102,18 @@ export class R3Injector {
*/
private destroyed = false;
constructor(def: InjectorType<any>, readonly parent: Injector) {
constructor(
def: InjectorType<any>, additionalProviders: StaticProvider[]|null,
readonly parent: Injector) {
// Start off by creating Records for every provider declared in every InjectorType
// included transitively in `def`.
deepForEach(
[def], injectorDef => this.processInjectorType(injectorDef, new Set<InjectorType<any>>()));
additionalProviders &&
deepForEach(additionalProviders, provider => this.processProvider(provider));
// Make sure the INJECTOR token provides this injector.
this.records.set(INJECTOR, makeRecord(undefined, this));
@ -284,20 +291,18 @@ export class R3Injector {
throw new Error(`Mixed multi-provider for ${token}.`);
}
} else {
token = provider;
multiRecord = makeRecord(undefined, NOT_YET, true);
multiRecord.factory = () => injectArgs(multiRecord !.multi !);
this.records.set(token, multiRecord);
}
token = provider;
multiRecord.multi !.push(provider);
} else {
const existing = this.records.get(token);
if (existing && existing.multi !== undefined) {
throw new Error(`Mixed multi-provider for ${stringify(token)}`);
}
}
const existing = this.records.get(token);
if (existing && existing.multi !== undefined) {
throw new Error(`Mixed multi-provider for ${token}`);
}
this.records.set(token, record);
}