refactor(core): Cleanup non-standard Injector
handling. (#39621)
Due to historical reasons `Injector.__NG_ELEMENT_ID__` was set to `-1`. This changes it to be consistent with other `*Ref.__NG_ELEMENT_ID__` constructs. PR Close #39621
This commit is contained in:
parent
585875c3f4
commit
8574c3000e
@ -255,21 +255,6 @@
|
|||||||
"packages/core/src/render3/definition.ts",
|
"packages/core/src/render3/definition.ts",
|
||||||
"packages/core/src/metadata/ng_module.ts"
|
"packages/core/src/metadata/ng_module.ts"
|
||||||
],
|
],
|
||||||
[
|
|
||||||
"packages/core/src/application_ref.ts",
|
|
||||||
"packages/core/src/application_tokens.ts",
|
|
||||||
"packages/core/src/linker/component_factory.ts",
|
|
||||||
"packages/core/src/change_detection/change_detection.ts",
|
|
||||||
"packages/core/src/change_detection/change_detector_ref.ts",
|
|
||||||
"packages/core/src/render3/view_ref.ts",
|
|
||||||
"packages/core/src/linker/view_container_ref.ts",
|
|
||||||
"packages/core/src/render3/di.ts",
|
|
||||||
"packages/core/src/di/injector_compatibility.ts",
|
|
||||||
"packages/core/src/di/injector.ts",
|
|
||||||
"packages/core/src/di/r3_injector.ts",
|
|
||||||
"packages/core/src/render3/definition.ts",
|
|
||||||
"packages/core/src/metadata/ng_module.ts"
|
|
||||||
],
|
|
||||||
[
|
[
|
||||||
"packages/core/src/application_ref.ts",
|
"packages/core/src/application_ref.ts",
|
||||||
"packages/core/src/application_tokens.ts",
|
"packages/core/src/application_tokens.ts",
|
||||||
@ -641,16 +626,6 @@
|
|||||||
"packages/core/src/render3/definition.ts",
|
"packages/core/src/render3/definition.ts",
|
||||||
"packages/core/src/metadata/ng_module.ts"
|
"packages/core/src/metadata/ng_module.ts"
|
||||||
],
|
],
|
||||||
[
|
|
||||||
"packages/core/src/application_ref.ts",
|
|
||||||
"packages/core/src/linker/compiler.ts",
|
|
||||||
"packages/core/src/render3/ng_module_ref.ts",
|
|
||||||
"packages/core/src/di/injector_compatibility.ts",
|
|
||||||
"packages/core/src/di/injector.ts",
|
|
||||||
"packages/core/src/di/r3_injector.ts",
|
|
||||||
"packages/core/src/render3/definition.ts",
|
|
||||||
"packages/core/src/metadata/ng_module.ts"
|
|
||||||
],
|
|
||||||
[
|
[
|
||||||
"packages/core/src/application_ref.ts",
|
"packages/core/src/application_ref.ts",
|
||||||
"packages/core/src/linker/compiler.ts",
|
"packages/core/src/linker/compiler.ts",
|
||||||
@ -786,20 +761,6 @@
|
|||||||
"packages/core/src/render3/definition.ts",
|
"packages/core/src/render3/definition.ts",
|
||||||
"packages/core/src/metadata/ng_module.ts"
|
"packages/core/src/metadata/ng_module.ts"
|
||||||
],
|
],
|
||||||
[
|
|
||||||
"packages/core/src/application_ref.ts",
|
|
||||||
"packages/core/src/metadata/resource_loading.ts",
|
|
||||||
"packages/core/src/metadata/directives.ts",
|
|
||||||
"packages/core/src/render3/jit/directive.ts",
|
|
||||||
"packages/core/src/render3/jit/environment.ts",
|
|
||||||
"packages/core/src/render3/index.ts",
|
|
||||||
"packages/core/src/render3/pipe.ts",
|
|
||||||
"packages/core/src/di/injector_compatibility.ts",
|
|
||||||
"packages/core/src/di/injector.ts",
|
|
||||||
"packages/core/src/di/r3_injector.ts",
|
|
||||||
"packages/core/src/render3/definition.ts",
|
|
||||||
"packages/core/src/metadata/ng_module.ts"
|
|
||||||
],
|
|
||||||
[
|
[
|
||||||
"packages/core/src/application_ref.ts",
|
"packages/core/src/application_ref.ts",
|
||||||
"packages/core/src/metadata/resource_loading.ts",
|
"packages/core/src/metadata/resource_loading.ts",
|
||||||
@ -900,6 +861,16 @@
|
|||||||
"packages/core/src/view/entrypoint.ts",
|
"packages/core/src/view/entrypoint.ts",
|
||||||
"packages/core/src/view/services.ts"
|
"packages/core/src/view/services.ts"
|
||||||
],
|
],
|
||||||
|
[
|
||||||
|
"packages/core/src/di.ts",
|
||||||
|
"packages/core/src/di/index.ts",
|
||||||
|
"packages/core/src/di/injectable.ts",
|
||||||
|
"packages/core/src/di/jit/injectable.ts",
|
||||||
|
"packages/core/src/di/jit/environment.ts",
|
||||||
|
"packages/core/src/di/injector_compatibility.ts",
|
||||||
|
"packages/core/src/di/injector.ts",
|
||||||
|
"packages/core/src/di/null_injector.ts"
|
||||||
|
],
|
||||||
[
|
[
|
||||||
"packages/core/src/di/injectable.ts",
|
"packages/core/src/di/injectable.ts",
|
||||||
"packages/core/src/di/jit/injectable.ts"
|
"packages/core/src/di/jit/injectable.ts"
|
||||||
@ -908,6 +879,11 @@
|
|||||||
"packages/core/src/di/injector_compatibility.ts",
|
"packages/core/src/di/injector_compatibility.ts",
|
||||||
"packages/core/src/di/injector.ts"
|
"packages/core/src/di/injector.ts"
|
||||||
],
|
],
|
||||||
|
[
|
||||||
|
"packages/core/src/di/injector_compatibility.ts",
|
||||||
|
"packages/core/src/di/injector.ts",
|
||||||
|
"packages/core/src/di/null_injector.ts"
|
||||||
|
],
|
||||||
[
|
[
|
||||||
"packages/core/src/di/injector_compatibility.ts",
|
"packages/core/src/di/injector_compatibility.ts",
|
||||||
"packages/core/src/di/injector.ts",
|
"packages/core/src/di/injector.ts",
|
||||||
@ -921,6 +897,10 @@
|
|||||||
"packages/core/src/metadata/ng_module.ts",
|
"packages/core/src/metadata/ng_module.ts",
|
||||||
"packages/core/src/di/util.ts"
|
"packages/core/src/di/util.ts"
|
||||||
],
|
],
|
||||||
|
[
|
||||||
|
"packages/core/src/di/injector_token.ts",
|
||||||
|
"packages/core/src/di/injector.ts"
|
||||||
|
],
|
||||||
[
|
[
|
||||||
"packages/core/src/di/injector.ts",
|
"packages/core/src/di/injector.ts",
|
||||||
"packages/core/src/di/r3_injector.ts"
|
"packages/core/src/di/r3_injector.ts"
|
||||||
|
4
goldens/public-api/core/core.d.ts
vendored
4
goldens/public-api/core/core.d.ts
vendored
@ -837,11 +837,11 @@ export declare interface RendererType2 {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export declare class ResolvedReflectiveFactory {
|
export declare class ResolvedReflectiveFactory {
|
||||||
dependencies: ɵangular_packages_core_core_e[];
|
dependencies: ɵangular_packages_core_core_d[];
|
||||||
factory: Function;
|
factory: Function;
|
||||||
constructor(
|
constructor(
|
||||||
factory: Function,
|
factory: Function,
|
||||||
dependencies: ɵangular_packages_core_core_e[]);
|
dependencies: ɵangular_packages_core_core_d[]);
|
||||||
}
|
}
|
||||||
|
|
||||||
export declare interface ResolvedReflectiveProvider {
|
export declare interface ResolvedReflectiveProvider {
|
||||||
|
@ -12,7 +12,7 @@
|
|||||||
"master": {
|
"master": {
|
||||||
"uncompressed": {
|
"uncompressed": {
|
||||||
"runtime-es2015": 3037,
|
"runtime-es2015": 3037,
|
||||||
"main-es2015": 449483,
|
"main-es2015": 448796,
|
||||||
"polyfills-es2015": 52415
|
"polyfills-es2015": 52415
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -21,7 +21,7 @@
|
|||||||
"master": {
|
"master": {
|
||||||
"uncompressed": {
|
"uncompressed": {
|
||||||
"runtime-es2015": 1485,
|
"runtime-es2015": 1485,
|
||||||
"main-es2015": 147252,
|
"main-es2015": 146680,
|
||||||
"polyfills-es2015": 36964
|
"polyfills-es2015": 36964
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -18,7 +18,8 @@ export {ɵɵdefineInjectable, defineInjectable, ɵɵdefineInjector, InjectableTy
|
|||||||
export {forwardRef, resolveForwardRef, ForwardRefFn} from './forward_ref';
|
export {forwardRef, resolveForwardRef, ForwardRefFn} from './forward_ref';
|
||||||
export {Injectable, InjectableDecorator, InjectableProvider} from './injectable';
|
export {Injectable, InjectableDecorator, InjectableProvider} from './injectable';
|
||||||
export {Injector} from './injector';
|
export {Injector} from './injector';
|
||||||
export {ɵɵinject, inject, INJECTOR, ɵɵinvalidFactoryDep} from './injector_compatibility';
|
export {ɵɵinject, inject, ɵɵinvalidFactoryDep} from './injector_compatibility';
|
||||||
|
export {INJECTOR} from './injector_token';
|
||||||
export {ReflectiveInjector} from './reflective_injector';
|
export {ReflectiveInjector} from './reflective_injector';
|
||||||
export {ClassProvider, ClassSansProvider, ConstructorProvider, ConstructorSansProvider, ExistingProvider, ExistingSansProvider, FactoryProvider, FactorySansProvider, Provider, StaticClassProvider, StaticClassSansProvider, StaticProvider, TypeProvider, ValueProvider, ValueSansProvider} from './interface/provider';
|
export {ClassProvider, ClassSansProvider, ConstructorProvider, ConstructorSansProvider, ExistingProvider, ExistingSansProvider, FactoryProvider, FactorySansProvider, Provider, StaticClassProvider, StaticClassSansProvider, StaticProvider, TypeProvider, ValueProvider, ValueSansProvider} from './interface/provider';
|
||||||
export {ResolvedReflectiveFactory, ResolvedReflectiveProvider} from './reflective_provider';
|
export {ResolvedReflectiveFactory, ResolvedReflectiveProvider} from './reflective_provider';
|
||||||
|
76
packages/core/src/di/inject_switch.ts
Normal file
76
packages/core/src/di/inject_switch.ts
Normal file
@ -0,0 +1,76 @@
|
|||||||
|
/**
|
||||||
|
* @license
|
||||||
|
* Copyright Google LLC All Rights Reserved.
|
||||||
|
*
|
||||||
|
* 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 {Type} from '../interface/type';
|
||||||
|
import {assertNotEqual} from '../util/assert';
|
||||||
|
import {stringify} from '../util/stringify';
|
||||||
|
import {InjectionToken} from './injection_token';
|
||||||
|
import {getInjectableDef, ɵɵInjectableDef} from './interface/defs';
|
||||||
|
import {InjectFlags} from './interface/injector';
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Current implementation of inject.
|
||||||
|
*
|
||||||
|
* By default, it is `injectInjectorOnly`, which makes it `Injector`-only aware. It can be changed
|
||||||
|
* to `directiveInject`, which brings in the `NodeInjector` system of ivy. It is designed this
|
||||||
|
* way for two reasons:
|
||||||
|
* 1. `Injector` should not depend on ivy logic.
|
||||||
|
* 2. To maintain tree shake-ability we don't want to bring in unnecessary code.
|
||||||
|
*/
|
||||||
|
let _injectImplementation: (<T>(token: Type<T>|InjectionToken<T>, flags?: InjectFlags) => T | null)|
|
||||||
|
undefined;
|
||||||
|
export function getInjectImplementation() {
|
||||||
|
return _injectImplementation;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets the current inject implementation.
|
||||||
|
*/
|
||||||
|
export function setInjectImplementation(
|
||||||
|
impl: (<T>(token: Type<T>|InjectionToken<T>, flags?: InjectFlags) => T | null)|
|
||||||
|
undefined): (<T>(token: Type<T>|InjectionToken<T>, flags?: InjectFlags) => T | null)|undefined {
|
||||||
|
const previous = _injectImplementation;
|
||||||
|
_injectImplementation = impl;
|
||||||
|
return previous;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Injects `root` tokens in limp mode.
|
||||||
|
*
|
||||||
|
* If no injector exists, we can still inject tree-shakable providers which have `providedIn` set to
|
||||||
|
* `"root"`. This is known as the limp mode injection. In such case the value is stored in the
|
||||||
|
* `InjectableDef`.
|
||||||
|
*/
|
||||||
|
export function injectRootLimpMode<T>(
|
||||||
|
token: Type<T>|InjectionToken<T>, notFoundValue: T|undefined, flags: InjectFlags): T|null {
|
||||||
|
const injectableDef: ɵɵInjectableDef<T>|null = getInjectableDef(token);
|
||||||
|
if (injectableDef && injectableDef.providedIn == 'root') {
|
||||||
|
return injectableDef.value === undefined ? injectableDef.value = injectableDef.factory() :
|
||||||
|
injectableDef.value;
|
||||||
|
}
|
||||||
|
if (flags & InjectFlags.Optional) return null;
|
||||||
|
if (notFoundValue !== undefined) return notFoundValue;
|
||||||
|
throw new Error(`Injector: NOT_FOUND [${stringify(token)}]`);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Assert that `_injectImplementation` is not `fn`.
|
||||||
|
*
|
||||||
|
* This is useful, to prevent infinite recursion.
|
||||||
|
*
|
||||||
|
* @param fn Function which it should not equal to
|
||||||
|
*/
|
||||||
|
export function assertInjectImplementationNotEqual(
|
||||||
|
fn: (<T>(token: Type<T>|InjectionToken<T>, flags?: InjectFlags) => T | null)) {
|
||||||
|
ngDevMode &&
|
||||||
|
assertNotEqual(_injectImplementation, fn, 'Calling ɵɵinject would cause infinite recursion');
|
||||||
|
}
|
@ -7,6 +7,7 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
import {Type} from '../interface/type';
|
import {Type} from '../interface/type';
|
||||||
|
import {assertLessThan} from '../util/assert';
|
||||||
|
|
||||||
import {ɵɵdefineInjectable} from './interface/defs';
|
import {ɵɵdefineInjectable} from './interface/defs';
|
||||||
|
|
||||||
@ -61,9 +62,10 @@ export class InjectionToken<T> {
|
|||||||
}) {
|
}) {
|
||||||
this.ɵprov = undefined;
|
this.ɵprov = undefined;
|
||||||
if (typeof options == 'number') {
|
if (typeof options == 'number') {
|
||||||
|
(typeof ngDevMode === 'undefined' || ngDevMode) &&
|
||||||
|
assertLessThan(options, 0, 'Only negative numbers are supported here');
|
||||||
// This is a special hack to assign __NG_ELEMENT_ID__ to this instance.
|
// This is a special hack to assign __NG_ELEMENT_ID__ to this instance.
|
||||||
// __NG_ELEMENT_ID__ is Used by Ivy to determine bloom filter id.
|
// See `InjectorMarkers`
|
||||||
// We are using it to assign `-1` which is used to identify `Injector`.
|
|
||||||
(this as any).__NG_ELEMENT_ID__ = options;
|
(this as any).__NG_ELEMENT_ID__ = options;
|
||||||
} else if (options !== undefined) {
|
} else if (options !== undefined) {
|
||||||
this.ɵprov = ɵɵdefineInjectable({
|
this.ɵprov = ɵɵdefineInjectable({
|
||||||
|
@ -8,14 +8,16 @@
|
|||||||
|
|
||||||
import {AbstractType, Type} from '../interface/type';
|
import {AbstractType, Type} from '../interface/type';
|
||||||
import {stringify} from '../util/stringify';
|
import {stringify} from '../util/stringify';
|
||||||
|
|
||||||
import {resolveForwardRef} from './forward_ref';
|
import {resolveForwardRef} from './forward_ref';
|
||||||
import {InjectionToken} from './injection_token';
|
import {InjectionToken} from './injection_token';
|
||||||
import {catchInjectorError, formatError, INJECTOR, NG_TEMP_TOKEN_PATH, NullInjector, setCurrentInjector, THROW_IF_NOT_FOUND, USE_VALUE, ɵɵinject} from './injector_compatibility';
|
import {catchInjectorError, formatError, NG_TEMP_TOKEN_PATH, setCurrentInjector, THROW_IF_NOT_FOUND, USE_VALUE, ɵɵinject} from './injector_compatibility';
|
||||||
|
import {InjectorMarkers} from './injector_marker';
|
||||||
|
import {INJECTOR} from './injector_token';
|
||||||
import {getInjectableDef, ɵɵdefineInjectable} from './interface/defs';
|
import {getInjectableDef, ɵɵdefineInjectable} from './interface/defs';
|
||||||
import {InjectFlags} from './interface/injector';
|
import {InjectFlags} from './interface/injector';
|
||||||
import {ConstructorProvider, ExistingProvider, FactoryProvider, StaticClassProvider, StaticProvider, ValueProvider} from './interface/provider';
|
import {ConstructorProvider, ExistingProvider, FactoryProvider, StaticClassProvider, StaticProvider, ValueProvider} from './interface/provider';
|
||||||
import {Inject, Optional, Self, SkipSelf} from './metadata';
|
import {Inject, Optional, Self, SkipSelf} from './metadata';
|
||||||
|
import {NullInjector} from './null_injector';
|
||||||
import {createInjector} from './r3_injector';
|
import {createInjector} from './r3_injector';
|
||||||
import {INJECTOR_SCOPE} from './scope';
|
import {INJECTOR_SCOPE} from './scope';
|
||||||
|
|
||||||
@ -113,7 +115,7 @@ export abstract class Injector {
|
|||||||
* @internal
|
* @internal
|
||||||
* @nocollapse
|
* @nocollapse
|
||||||
*/
|
*/
|
||||||
static __NG_ELEMENT_ID__ = -1;
|
static __NG_ELEMENT_ID__ = InjectorMarkers.Injector;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -14,28 +14,14 @@ import {getClosureSafeProperty} from '../util/property';
|
|||||||
import {stringify} from '../util/stringify';
|
import {stringify} from '../util/stringify';
|
||||||
|
|
||||||
import {resolveForwardRef} from './forward_ref';
|
import {resolveForwardRef} from './forward_ref';
|
||||||
|
import {getInjectImplementation, injectRootLimpMode} from './inject_switch';
|
||||||
import {InjectionToken} from './injection_token';
|
import {InjectionToken} from './injection_token';
|
||||||
import {Injector} from './injector';
|
import {Injector} from './injector';
|
||||||
import {getInjectableDef, ɵɵInjectableDef} from './interface/defs';
|
|
||||||
import {InjectFlags} from './interface/injector';
|
import {InjectFlags} from './interface/injector';
|
||||||
import {ValueProvider} from './interface/provider';
|
import {ValueProvider} from './interface/provider';
|
||||||
import {Inject, Optional, Self, SkipSelf} from './metadata';
|
import {Inject, Optional, Self, SkipSelf} from './metadata';
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* An InjectionToken that gets the current `Injector` for `createInjector()`-style injectors.
|
|
||||||
*
|
|
||||||
* Requesting this token instead of `Injector` allows `StaticInjector` to be tree-shaken from a
|
|
||||||
* project.
|
|
||||||
*
|
|
||||||
* @publicApi
|
|
||||||
*/
|
|
||||||
export const INJECTOR = new InjectionToken<Injector>(
|
|
||||||
'INJECTOR',
|
|
||||||
-1 as any // `-1` is used by Ivy DI system as special value to recognize it as `Injector`.
|
|
||||||
);
|
|
||||||
|
|
||||||
const _THROW_IF_NOT_FOUND = {};
|
const _THROW_IF_NOT_FOUND = {};
|
||||||
export const THROW_IF_NOT_FOUND = _THROW_IF_NOT_FOUND;
|
export const THROW_IF_NOT_FOUND = _THROW_IF_NOT_FOUND;
|
||||||
|
|
||||||
@ -62,41 +48,6 @@ export function setCurrentInjector(injector: Injector|null|undefined): Injector|
|
|||||||
return former;
|
return former;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Current implementation of inject.
|
|
||||||
*
|
|
||||||
* By default, it is `injectInjectorOnly`, which makes it `Injector`-only aware. It can be changed
|
|
||||||
* to `directiveInject`, which brings in the `NodeInjector` system of ivy. It is designed this
|
|
||||||
* way for two reasons:
|
|
||||||
* 1. `Injector` should not depend on ivy logic.
|
|
||||||
* 2. To maintain tree shake-ability we don't want to bring in unnecessary code.
|
|
||||||
*/
|
|
||||||
let _injectImplementation: (<T>(token: Type<T>|InjectionToken<T>, flags?: InjectFlags) => T | null)|
|
|
||||||
undefined;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Sets the current inject implementation.
|
|
||||||
*/
|
|
||||||
export function setInjectImplementation(
|
|
||||||
impl: (<T>(token: Type<T>|InjectionToken<T>, flags?: InjectFlags) => T | null)|
|
|
||||||
undefined): (<T>(token: Type<T>|InjectionToken<T>, flags?: InjectFlags) => T | null)|undefined {
|
|
||||||
const previous = _injectImplementation;
|
|
||||||
_injectImplementation = impl;
|
|
||||||
return previous;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Assert that `_injectImplementation` is not `fn`.
|
|
||||||
*
|
|
||||||
* This is useful, to prevent infinite recursion.
|
|
||||||
*
|
|
||||||
* @param fn Function which it should not equal to
|
|
||||||
*/
|
|
||||||
export function assertInjectImplementationNot(
|
|
||||||
fn: (<T>(token: Type<T>|InjectionToken<T>, flags?: InjectFlags) => T | null)) {
|
|
||||||
ngDevMode &&
|
|
||||||
assertNotEqual(_injectImplementation, fn, 'Calling ɵɵinject would cause infinite recursion');
|
|
||||||
}
|
|
||||||
|
|
||||||
export function injectInjectorOnly<T>(token: Type<T>|InjectionToken<T>): T;
|
export function injectInjectorOnly<T>(token: Type<T>|InjectionToken<T>): T;
|
||||||
export function injectInjectorOnly<T>(token: Type<T>|InjectionToken<T>, flags?: InjectFlags): T|
|
export function injectInjectorOnly<T>(token: Type<T>|InjectionToken<T>, flags?: InjectFlags): T|
|
||||||
@ -128,7 +79,7 @@ export function injectInjectorOnly<T>(
|
|||||||
export function ɵɵinject<T>(token: Type<T>|InjectionToken<T>): T;
|
export function ɵɵinject<T>(token: Type<T>|InjectionToken<T>): T;
|
||||||
export function ɵɵinject<T>(token: Type<T>|InjectionToken<T>, flags?: InjectFlags): T|null;
|
export function ɵɵinject<T>(token: Type<T>|InjectionToken<T>, flags?: InjectFlags): T|null;
|
||||||
export function ɵɵinject<T>(token: Type<T>|InjectionToken<T>, flags = InjectFlags.Default): T|null {
|
export function ɵɵinject<T>(token: Type<T>|InjectionToken<T>, flags = InjectFlags.Default): T|null {
|
||||||
return (_injectImplementation || injectInjectorOnly)(resolveForwardRef(token), flags);
|
return (getInjectImplementation() || injectInjectorOnly)(resolveForwardRef(token), flags);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -181,24 +132,6 @@ Please check that 1) the type for the parameter at index ${
|
|||||||
*/
|
*/
|
||||||
export const inject = ɵɵinject;
|
export const inject = ɵɵinject;
|
||||||
|
|
||||||
/**
|
|
||||||
* Injects `root` tokens in limp mode.
|
|
||||||
*
|
|
||||||
* If no injector exists, we can still inject tree-shakable providers which have `providedIn` set to
|
|
||||||
* `"root"`. This is known as the limp mode injection. In such case the value is stored in the
|
|
||||||
* `InjectableDef`.
|
|
||||||
*/
|
|
||||||
export function injectRootLimpMode<T>(
|
|
||||||
token: Type<T>|InjectionToken<T>, notFoundValue: T|undefined, flags: InjectFlags): T|null {
|
|
||||||
const injectableDef: ɵɵInjectableDef<T>|null = getInjectableDef(token);
|
|
||||||
if (injectableDef && injectableDef.providedIn == 'root') {
|
|
||||||
return injectableDef.value === undefined ? injectableDef.value = injectableDef.factory() :
|
|
||||||
injectableDef.value;
|
|
||||||
}
|
|
||||||
if (flags & InjectFlags.Optional) return null;
|
|
||||||
if (notFoundValue !== undefined) return notFoundValue;
|
|
||||||
throw new Error(`Injector: NOT_FOUND [${stringify(token)}]`);
|
|
||||||
}
|
|
||||||
|
|
||||||
export function injectArgs(types: (Type<any>|InjectionToken<any>|any[])[]): any[] {
|
export function injectArgs(types: (Type<any>|InjectionToken<any>|any[])[]): any[] {
|
||||||
const args: any[] = [];
|
const args: any[] = [];
|
||||||
@ -236,22 +169,6 @@ export function injectArgs(types: (Type<any>|InjectionToken<any>|any[])[]): any[
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
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.
|
|
||||||
// TODO(misko): uncomment the next line once `ngDevMode` works with closure.
|
|
||||||
// if (ngDevMode) debugger;
|
|
||||||
const error = new Error(`NullInjectorError: No provider for ${stringify(token)}!`);
|
|
||||||
error.name = 'NullInjectorError';
|
|
||||||
throw error;
|
|
||||||
}
|
|
||||||
return notFoundValue;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
export function catchInjectorError(
|
export function catchInjectorError(
|
||||||
e: any, token: any, injectorErrorName: string, source: string|null): never {
|
e: any, token: any, injectorErrorName: string, source: string|null): never {
|
||||||
const tokenPath: any[] = e[NG_TEMP_TOKEN_PATH];
|
const tokenPath: any[] = e[NG_TEMP_TOKEN_PATH];
|
||||||
|
24
packages/core/src/di/injector_marker.ts
Normal file
24
packages/core/src/di/injector_marker.ts
Normal file
@ -0,0 +1,24 @@
|
|||||||
|
/**
|
||||||
|
* @license
|
||||||
|
* Copyright Google LLC All Rights Reserved.
|
||||||
|
*
|
||||||
|
* 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
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Special markers which can be left on `Type.__NG_ELEMENT_ID__` which are used by the Ivy's
|
||||||
|
* `NodeInjector`. Usually these markers contain factory functions. But in case of this special
|
||||||
|
* marker we can't leave behind a function because it would create tree shaking problem.
|
||||||
|
*
|
||||||
|
* Currently only `Injector` is special.
|
||||||
|
*
|
||||||
|
* NOTE: the numbers here must be negative, because positive numbers are used as IDs for bloom
|
||||||
|
* filter.
|
||||||
|
*/
|
||||||
|
export const enum InjectorMarkers {
|
||||||
|
/**
|
||||||
|
* Marks that the current type is `Injector`
|
||||||
|
*/
|
||||||
|
Injector = -1
|
||||||
|
}
|
28
packages/core/src/di/injector_token.ts
Normal file
28
packages/core/src/di/injector_token.ts
Normal file
@ -0,0 +1,28 @@
|
|||||||
|
/**
|
||||||
|
* @license
|
||||||
|
* Copyright Google LLC All Rights Reserved.
|
||||||
|
*
|
||||||
|
* 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 {InjectionToken} from './injection_token';
|
||||||
|
import {Injector} from './injector';
|
||||||
|
import {InjectorMarkers} from './injector_marker';
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* An InjectionToken that gets the current `Injector` for `createInjector()`-style injectors.
|
||||||
|
*
|
||||||
|
* Requesting this token instead of `Injector` allows `StaticInjector` to be tree-shaken from a
|
||||||
|
* project.
|
||||||
|
*
|
||||||
|
* @publicApi
|
||||||
|
*/
|
||||||
|
export const INJECTOR = new InjectionToken<Injector>(
|
||||||
|
'INJECTOR',
|
||||||
|
// Dissable tslint because this is const enum which gets inlined not top level prop access.
|
||||||
|
// tslint:disable-next-line: no-toplevel-property-access
|
||||||
|
InjectorMarkers.Injector as any, // Special value used by Ivy to identify `Injector`.
|
||||||
|
);
|
23
packages/core/src/di/null_injector.ts
Normal file
23
packages/core/src/di/null_injector.ts
Normal file
@ -0,0 +1,23 @@
|
|||||||
|
/**
|
||||||
|
* @license
|
||||||
|
* Copyright Google LLC All Rights Reserved.
|
||||||
|
*
|
||||||
|
* 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 {stringify} from '../util/stringify';
|
||||||
|
import {Injector} from '.';
|
||||||
|
import {THROW_IF_NOT_FOUND} from './injector_compatibility';
|
||||||
|
|
||||||
|
|
||||||
|
export class NullInjector implements Injector {
|
||||||
|
get(token: any, notFoundValue: any = THROW_IF_NOT_FOUND): any {
|
||||||
|
if (notFoundValue === THROW_IF_NOT_FOUND) {
|
||||||
|
const error = new Error(`NullInjectorError: No provider for ${stringify(token)}!`);
|
||||||
|
error.name = 'NullInjectorError';
|
||||||
|
throw error;
|
||||||
|
}
|
||||||
|
return notFoundValue;
|
||||||
|
}
|
||||||
|
}
|
@ -19,10 +19,12 @@ import {stringify} from '../util/stringify';
|
|||||||
import {resolveForwardRef} from './forward_ref';
|
import {resolveForwardRef} from './forward_ref';
|
||||||
import {InjectionToken} from './injection_token';
|
import {InjectionToken} from './injection_token';
|
||||||
import {Injector} from './injector';
|
import {Injector} from './injector';
|
||||||
import {catchInjectorError, injectArgs, INJECTOR, NG_TEMP_TOKEN_PATH, NullInjector, setCurrentInjector, THROW_IF_NOT_FOUND, USE_VALUE, ɵɵinject} from './injector_compatibility';
|
import {catchInjectorError, injectArgs, NG_TEMP_TOKEN_PATH, setCurrentInjector, THROW_IF_NOT_FOUND, USE_VALUE, ɵɵinject} from './injector_compatibility';
|
||||||
|
import {INJECTOR} from './injector_token';
|
||||||
import {getInheritedInjectableDef, getInjectableDef, getInjectorDef, InjectorType, InjectorTypeWithProviders, ɵɵInjectableDef} from './interface/defs';
|
import {getInheritedInjectableDef, getInjectableDef, getInjectorDef, InjectorType, InjectorTypeWithProviders, ɵɵInjectableDef} from './interface/defs';
|
||||||
import {InjectFlags} from './interface/injector';
|
import {InjectFlags} from './interface/injector';
|
||||||
import {ClassProvider, ConstructorProvider, ExistingProvider, FactoryProvider, StaticClassProvider, StaticProvider, TypeProvider, ValueProvider} from './interface/provider';
|
import {ClassProvider, ConstructorProvider, ExistingProvider, FactoryProvider, StaticClassProvider, StaticProvider, TypeProvider, ValueProvider} from './interface/provider';
|
||||||
|
import {NullInjector} from './null_injector';
|
||||||
import {INJECTOR_SCOPE} from './scope';
|
import {INJECTOR_SCOPE} from './scope';
|
||||||
|
|
||||||
|
|
||||||
|
@ -7,9 +7,10 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
import {isForwardRef, resolveForwardRef} from '../di/forward_ref';
|
import {isForwardRef, resolveForwardRef} from '../di/forward_ref';
|
||||||
|
import {injectRootLimpMode, setInjectImplementation} from '../di/inject_switch';
|
||||||
import {InjectionToken} from '../di/injection_token';
|
import {InjectionToken} from '../di/injection_token';
|
||||||
import {Injector} from '../di/injector';
|
import {Injector} from '../di/injector';
|
||||||
import {injectRootLimpMode, setInjectImplementation} from '../di/injector_compatibility';
|
import {InjectorMarkers} from '../di/injector_marker';
|
||||||
import {getInjectorDef} from '../di/interface/defs';
|
import {getInjectorDef} from '../di/interface/defs';
|
||||||
import {InjectFlags} from '../di/interface/injector';
|
import {InjectFlags} from '../di/interface/injector';
|
||||||
import {Type} from '../interface/type';
|
import {Type} from '../interface/type';
|
||||||
@ -415,8 +416,11 @@ export function getOrCreateInjectable<T>(
|
|||||||
// so just call the factory function to create it.
|
// so just call the factory function to create it.
|
||||||
if (typeof bloomHash === 'function') {
|
if (typeof bloomHash === 'function') {
|
||||||
if (!enterDI(lView, tNode, flags)) {
|
if (!enterDI(lView, tNode, flags)) {
|
||||||
// Failed to enter DI use module injector instead.
|
// Failed to enter DI, try module injector instead. If a token is injected with the @Host
|
||||||
return lookupTokenUsingModuleInjector<T>(lView, token, flags, notFoundValue);
|
// flag, the module injector is not searched for that token in Ivy.
|
||||||
|
return (flags & InjectFlags.Host) ?
|
||||||
|
notFoundValueOrThrow<T>(notFoundValue, token, flags) :
|
||||||
|
lookupTokenUsingModuleInjector<T>(lView, token, flags, notFoundValue);
|
||||||
}
|
}
|
||||||
try {
|
try {
|
||||||
const value = bloomHash();
|
const value = bloomHash();
|
||||||
@ -429,32 +433,6 @@ export function getOrCreateInjectable<T>(
|
|||||||
leaveDI();
|
leaveDI();
|
||||||
}
|
}
|
||||||
} else if (typeof bloomHash === 'number') {
|
} else if (typeof bloomHash === 'number') {
|
||||||
// This is a value used to identify __NG_ELEMENT_ID__
|
|
||||||
// `-1` is a special value used to identify `Injector` types in NodeInjector
|
|
||||||
// This is a workaround for the fact that if the `Injector.__NG_ELEMENT_ID__`
|
|
||||||
// would have a factory function (such as `ElementRef`) it would cause Ivy
|
|
||||||
// to be pulled into the ViewEngine, because they both share `Injector` type.
|
|
||||||
// This should be refactored to follow `ElementRef` pattern once ViewEngine is
|
|
||||||
// removed
|
|
||||||
if (bloomHash === -1) {
|
|
||||||
if (!enterDI(lView, tNode, flags)) {
|
|
||||||
// Failed to enter DI, try module injector instead. If a token is injected with the @Host
|
|
||||||
// flag, the module injector is not searched for that token in Ivy.
|
|
||||||
return (flags & InjectFlags.Host) ?
|
|
||||||
notFoundValueOrThrow<T>(notFoundValue, token, flags) :
|
|
||||||
lookupTokenUsingModuleInjector<T>(lView, token, flags, notFoundValue);
|
|
||||||
}
|
|
||||||
try {
|
|
||||||
// Retrieving current `TNode` and `LView` from the state (rather than using `tNode` and
|
|
||||||
// `lView`), because entering DI (by calling `enterDI`) may cause these values to change
|
|
||||||
// (in case `@SkipSelf` flag is present).
|
|
||||||
return new NodeInjector(getCurrentTNode()! as TDirectiveHostNode, getLView()) as any;
|
|
||||||
} finally {
|
|
||||||
leaveDI();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// If the token has a bloom hash, then it is a token which could be in NodeInjector.
|
|
||||||
|
|
||||||
// A reference to the previous injector TView that was found while climbing the element
|
// A reference to the previous injector TView that was found while climbing the element
|
||||||
// injector tree. This is used to know if viewProviders can be accessed on the current
|
// injector tree. This is used to know if viewProviders can be accessed on the current
|
||||||
// injector.
|
// injector.
|
||||||
@ -525,6 +503,10 @@ export function getOrCreateInjectable<T>(
|
|||||||
|
|
||||||
const NOT_FOUND = {};
|
const NOT_FOUND = {};
|
||||||
|
|
||||||
|
export function createNodeInjector(): Injector {
|
||||||
|
return new NodeInjector(getCurrentTNode()! as TDirectiveHostNode, getLView()) as any;
|
||||||
|
}
|
||||||
|
|
||||||
function searchTokensOnInjector<T>(
|
function searchTokensOnInjector<T>(
|
||||||
injectorIndex: number, lView: LView, token: Type<T>|InjectionToken<T>,
|
injectorIndex: number, lView: LView, token: Type<T>|InjectionToken<T>,
|
||||||
previousTView: TView|null, flags: InjectFlags, hostTElementNode: TNode|null) {
|
previousTView: TView|null, flags: InjectFlags, hostTElementNode: TNode|null) {
|
||||||
@ -674,7 +656,17 @@ export function bloomHashBitOrFactory(token: Type<any>|InjectionToken<any>|strin
|
|||||||
// First check with `hasOwnProperty` so we don't get an inherited ID.
|
// First check with `hasOwnProperty` so we don't get an inherited ID.
|
||||||
token.hasOwnProperty(NG_ELEMENT_ID) ? (token as any)[NG_ELEMENT_ID] : undefined;
|
token.hasOwnProperty(NG_ELEMENT_ID) ? (token as any)[NG_ELEMENT_ID] : undefined;
|
||||||
// Negative token IDs are used for special objects such as `Injector`
|
// Negative token IDs are used for special objects such as `Injector`
|
||||||
return (typeof tokenId === 'number' && tokenId > 0) ? tokenId & BLOOM_MASK : tokenId;
|
if (typeof tokenId === 'number') {
|
||||||
|
if (tokenId >= 0) {
|
||||||
|
return tokenId & BLOOM_MASK;
|
||||||
|
} else {
|
||||||
|
ngDevMode &&
|
||||||
|
assertEqual(tokenId, InjectorMarkers.Injector, 'Expecting to get Special Injector Id');
|
||||||
|
return createNodeInjector;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
return tokenId;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export function bloomHasToken(bloomHash: number, injectorIndex: number, injectorView: LView|TData) {
|
export function bloomHasToken(bloomHash: number, injectorIndex: number, injectorView: LView|TData) {
|
||||||
|
@ -6,7 +6,8 @@
|
|||||||
* found in the LICENSE file at https://angular.io/license
|
* found in the LICENSE file at https://angular.io/license
|
||||||
*/
|
*/
|
||||||
import {InjectFlags, InjectionToken, resolveForwardRef} from '../../di';
|
import {InjectFlags, InjectionToken, resolveForwardRef} from '../../di';
|
||||||
import {assertInjectImplementationNot, ɵɵinject} from '../../di/injector_compatibility';
|
import {assertInjectImplementationNotEqual} from '../../di/inject_switch';
|
||||||
|
import {ɵɵinject} from '../../di/injector_compatibility';
|
||||||
import {Type} from '../../interface/type';
|
import {Type} from '../../interface/type';
|
||||||
import {getOrCreateInjectable, injectAttributeImpl} from '../di';
|
import {getOrCreateInjectable, injectAttributeImpl} from '../di';
|
||||||
import {TDirectiveHostNode} from '../interfaces/node';
|
import {TDirectiveHostNode} from '../interfaces/node';
|
||||||
@ -45,7 +46,7 @@ export function ɵɵdirectiveInject<T>(
|
|||||||
// if inject utilities are used before bootstrapping.
|
// if inject utilities are used before bootstrapping.
|
||||||
if (lView === null) {
|
if (lView === null) {
|
||||||
// Verify that we will not get into infinite loop.
|
// Verify that we will not get into infinite loop.
|
||||||
ngDevMode && assertInjectImplementationNot(ɵɵdirectiveInject);
|
ngDevMode && assertInjectImplementationNotEqual(ɵɵdirectiveInject);
|
||||||
return ɵɵinject(token, flags);
|
return ɵɵinject(token, flags);
|
||||||
}
|
}
|
||||||
const tNode = getCurrentTNode();
|
const tNode = getCurrentTNode();
|
||||||
|
@ -7,7 +7,7 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
import {Injector} from '../di/injector';
|
import {Injector} from '../di/injector';
|
||||||
import {INJECTOR} from '../di/injector_compatibility';
|
import {INJECTOR} from '../di/injector_token';
|
||||||
import {InjectFlags} from '../di/interface/injector';
|
import {InjectFlags} from '../di/interface/injector';
|
||||||
import {createInjectorWithoutInjectorInstances, R3Injector} from '../di/r3_injector';
|
import {createInjectorWithoutInjectorInstances, R3Injector} from '../di/r3_injector';
|
||||||
import {Type} from '../interface/type';
|
import {Type} from '../interface/type';
|
||||||
|
@ -8,8 +8,7 @@
|
|||||||
|
|
||||||
import {WrappedValue} from '../change_detection/change_detection_util';
|
import {WrappedValue} from '../change_detection/change_detection_util';
|
||||||
import {PipeTransform} from '../change_detection/pipe_transform';
|
import {PipeTransform} from '../change_detection/pipe_transform';
|
||||||
import {setInjectImplementation} from '../di/injector_compatibility';
|
import {setInjectImplementation} from '../di/inject_switch';
|
||||||
|
|
||||||
import {getFactoryDef} from './definition';
|
import {getFactoryDef} from './definition';
|
||||||
import {setIncludeViewProviders} from './di';
|
import {setIncludeViewProviders} from './di';
|
||||||
import {RuntimeError, RuntimeErrorCode} from './error_code';
|
import {RuntimeError, RuntimeErrorCode} from './error_code';
|
||||||
|
@ -8,7 +8,8 @@
|
|||||||
|
|
||||||
import {resolveForwardRef} from '../di/forward_ref';
|
import {resolveForwardRef} from '../di/forward_ref';
|
||||||
import {Injector} from '../di/injector';
|
import {Injector} from '../di/injector';
|
||||||
import {INJECTOR, setCurrentInjector} from '../di/injector_compatibility';
|
import {setCurrentInjector} from '../di/injector_compatibility';
|
||||||
|
import {INJECTOR} from '../di/injector_token';
|
||||||
import {getInjectableDef, ɵɵInjectableDef} from '../di/interface/defs';
|
import {getInjectableDef, ɵɵInjectableDef} from '../di/interface/defs';
|
||||||
import {INJECTOR_SCOPE} from '../di/scope';
|
import {INJECTOR_SCOPE} from '../di/scope';
|
||||||
import {NgModuleRef} from '../linker/ng_module_factory';
|
import {NgModuleRef} from '../linker/ng_module_factory';
|
||||||
|
@ -833,6 +833,9 @@
|
|||||||
{
|
{
|
||||||
"name": "createLView"
|
"name": "createLView"
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"name": "createNodeInjector"
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"name": "createPlatformFactory"
|
"name": "createPlatformFactory"
|
||||||
},
|
},
|
||||||
|
@ -1073,6 +1073,9 @@
|
|||||||
{
|
{
|
||||||
"name": "createNewSegmentGroup"
|
"name": "createNewSegmentGroup"
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"name": "createNodeInjector"
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"name": "createPlatformFactory"
|
"name": "createPlatformFactory"
|
||||||
},
|
},
|
||||||
|
@ -272,6 +272,9 @@
|
|||||||
{
|
{
|
||||||
"name": "createLView"
|
"name": "createLView"
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"name": "createNodeInjector"
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"name": "createTView"
|
"name": "createTView"
|
||||||
},
|
},
|
||||||
|
@ -9,7 +9,7 @@
|
|||||||
import {NgModuleRef, ɵINJECTOR_SCOPE as INJECTOR_SCOPE} from '@angular/core';
|
import {NgModuleRef, ɵINJECTOR_SCOPE as INJECTOR_SCOPE} from '@angular/core';
|
||||||
import {inject, InjectFlags} from '@angular/core/src/di';
|
import {inject, InjectFlags} from '@angular/core/src/di';
|
||||||
import {Injector} from '@angular/core/src/di/injector';
|
import {Injector} from '@angular/core/src/di/injector';
|
||||||
import {INJECTOR} from '@angular/core/src/di/injector_compatibility';
|
import {INJECTOR} from '@angular/core/src/di/injector_token';
|
||||||
import {ɵɵdefineInjectable, ɵɵInjectableDef} from '@angular/core/src/di/interface/defs';
|
import {ɵɵdefineInjectable, ɵɵInjectableDef} from '@angular/core/src/di/interface/defs';
|
||||||
import {NgModuleDefinition, NgModuleProviderDef, NodeFlags} from '@angular/core/src/view';
|
import {NgModuleDefinition, NgModuleProviderDef, NodeFlags} from '@angular/core/src/view';
|
||||||
import {moduleDef} from '@angular/core/src/view/ng_module';
|
import {moduleDef} from '@angular/core/src/view/ng_module';
|
||||||
|
Loading…
x
Reference in New Issue
Block a user