static-injector 2.1.1 → 2.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/import/commonjs/index.js +127 -197
- package/import/{es2015 → es2022}/di/create_injector.js +0 -2
- package/import/{es2015 → es2022}/di/forward_ref.js +29 -2
- package/import/{es2015 → es2022}/di/injection_token.js +5 -3
- package/import/{es2015 → es2022}/di/injector.js +15 -16
- package/import/{es2015 → es2022}/di/injector_compatibility.js +8 -3
- package/import/{es2015 → es2022}/di/interface/defs.js +2 -16
- package/import/{es2015 → es2022}/di/interface/injector.js +1 -1
- package/import/es2022/di/provider_collection.js +104 -0
- package/import/{es2015 → es2022}/di/r3_injector.js +46 -15
- package/import/{es2015 → es2022}/errors.js +4 -2
- package/import/{es2015 → es2022}/render3/error_code.js +1 -0
- package/import/es2022/render3/fields.js +22 -0
- package/import/{fesm2015 → fesm2022}/index.js +127 -198
- package/import/typings/di/create_injector.d.ts +3 -5
- package/import/typings/di/forward_ref.d.ts +29 -2
- package/import/typings/di/inject_switch.d.ts +1 -1
- package/import/typings/di/injection_token.d.ts +1 -1
- package/import/typings/di/injector.d.ts +3 -3
- package/import/typings/di/injector_compatibility.d.ts +1 -0
- package/import/typings/di/interface/defs.d.ts +2 -1
- package/import/typings/di/interface/injector.d.ts +2 -2
- package/import/typings/di/interface/provider.d.ts +7 -7
- package/import/typings/di/metadata.d.ts +4 -4
- package/import/typings/di/provider_collection.d.ts +1 -12
- package/import/typings/di/r3_injector.d.ts +8 -6
- package/import/typings/di/scope.d.ts +1 -1
- package/import/typings/errors.d.ts +28 -3
- package/import/typings/render3/fields.d.ts +9 -0
- package/import/typings/util/decorators.d.ts +1 -0
- package/package.json +7 -7
- package/readme.md +4 -1
- package/transform/compiler/src/injectable_compiler_2.d.ts +0 -1
- package/transform/compiler/src/injectable_compiler_2.js +31 -16
- package/transform/compiler/src/output/output_ast.d.ts +53 -10
- package/transform/compiler/src/output/output_ast.js +211 -12
- package/transform/compiler/src/parse_util.js +10 -0
- package/transform/compiler/src/render3/partial/api.js +1 -1
- package/transform/compiler/src/render3/r3_factory.d.ts +0 -8
- package/transform/compiler/src/render3/r3_factory.js +5 -4
- package/transform/compiler/src/render3/r3_identifiers.js +37 -37
- package/transform/compiler/src/render3/view/util.js +1 -3
- package/transform/compiler-cli/src/ngtsc/annotations/common/src/di.js +2 -4
- package/transform/compiler-cli/src/ngtsc/annotations/common/src/factory.js +1 -0
- package/transform/compiler-cli/src/ngtsc/annotations/common/src/util.d.ts +1 -1
- package/transform/compiler-cli/src/ngtsc/annotations/common/src/util.js +5 -9
- package/transform/compiler-cli/src/ngtsc/annotations/src/injectable.d.ts +2 -1
- package/transform/compiler-cli/src/ngtsc/annotations/src/injectable.js +12 -8
- package/transform/compiler-cli/src/ngtsc/diagnostics/error.d.ts +2 -2
- package/transform/compiler-cli/src/ngtsc/diagnostics/error.js +8 -4
- package/transform/compiler-cli/src/ngtsc/diagnostics/error_code.js +1 -1
- package/transform/compiler-cli/src/ngtsc/imports/src/default.js +1 -2
- package/transform/compiler-cli/src/ngtsc/reflection/src/host.d.ts +24 -173
- package/transform/compiler-cli/src/ngtsc/reflection/src/host.js +2 -51
- package/transform/compiler-cli/src/ngtsc/reflection/src/typescript.d.ts +5 -3
- package/transform/compiler-cli/src/ngtsc/reflection/src/typescript.js +5 -10
- package/transform/compiler-cli/src/ngtsc/transform/src/api.d.ts +5 -23
- package/transform/compiler-cli/src/ngtsc/transform/src/api.js +0 -21
- package/transform/compiler-cli/src/ngtsc/transform/src/utils.js +1 -2
- package/transform/compiler-cli/src/ngtsc/translator/src/api/ast_factory.d.ts +7 -0
- package/transform/compiler-cli/src/ngtsc/translator/src/context.js +1 -0
- package/transform/compiler-cli/src/ngtsc/translator/src/import_manager.js +4 -2
- package/transform/compiler-cli/src/ngtsc/translator/src/translator.d.ts +1 -0
- package/transform/compiler-cli/src/ngtsc/translator/src/translator.js +10 -4
- package/transform/compiler-cli/src/ngtsc/translator/src/typescript_ast_factory.d.ts +2 -1
- package/transform/compiler-cli/src/ngtsc/translator/src/typescript_ast_factory.js +20 -16
- package/transform/injectable-transform.d.ts +2 -2
- package/transform/injectable-transform.js +32 -6
- package/import/es2015/di/provider_collection.js +0 -244
- package/import/es2015/render3/fields.js +0 -11
- /package/import/{es2015 → es2022}/di/initializer_token.js +0 -0
- /package/import/{es2015 → es2022}/di/inject_switch.js +0 -0
- /package/import/{es2015 → es2022}/di/injectable.js +0 -0
- /package/import/{es2015 → es2022}/di/injector_marker.js +0 -0
- /package/import/{es2015 → es2022}/di/injector_token.js +0 -0
- /package/import/{es2015 → es2022}/di/interface/provider.js +0 -0
- /package/import/{es2015 → es2022}/di/internal_tokens.js +0 -0
- /package/import/{es2015 → es2022}/di/metadata.js +0 -0
- /package/import/{es2015 → es2022}/di/null_injector.js +0 -0
- /package/import/{es2015 → es2022}/di/provider_token.js +0 -0
- /package/import/{es2015 → es2022}/di/scope.js +0 -0
- /package/import/{es2015 → es2022}/error_details_base_url.js +0 -0
- /package/import/{es2015 → es2022}/index.js +0 -0
- /package/import/{es2015 → es2022}/interface/lifecycle_hooks.js +0 -0
- /package/import/{es2015 → es2022}/interface/type.js +0 -0
- /package/import/{es2015 → es2022}/render3/definition_factory.js +0 -0
- /package/import/{es2015 → es2022}/render3/di.js +0 -0
- /package/import/{es2015 → es2022}/render3/errors_di.js +0 -0
- /package/import/{es2015 → es2022}/render3/instructions/di.js +0 -0
- /package/import/{es2015 → es2022}/render3/util/stringify_utils.js +0 -0
- /package/import/{es2015 → es2022}/util/array_utils.js +0 -0
- /package/import/{es2015 → es2022}/util/closure.js +0 -0
- /package/import/{es2015 → es2022}/util/decorators.js +0 -0
- /package/import/{es2015 → es2022}/util/empty.js +0 -0
- /package/import/{es2015 → es2022}/util/property.js +0 -0
- /package/import/{es2015 → es2022}/util/stringify.js +0 -0
package/import/commonjs/index.js
CHANGED
|
@@ -108,9 +108,11 @@ function makeParamDecorator(name, props, parentClass) {
|
|
|
108
108
|
*
|
|
109
109
|
* Note: the `message` argument contains a descriptive error message as a string in development
|
|
110
110
|
* mode (when the `ngDevMode` is defined). In production mode (after tree-shaking pass), the
|
|
111
|
-
* `message` argument becomes `false`, thus we account for it in the typings and the runtime
|
|
111
|
+
* `message` argument becomes `false`, thus we account for it in the typings and the runtime
|
|
112
|
+
* logic.
|
|
112
113
|
*/
|
|
113
114
|
class RuntimeError extends Error {
|
|
115
|
+
code;
|
|
114
116
|
constructor(code, message) {
|
|
115
117
|
super(formatRuntimeError(code, message));
|
|
116
118
|
this.code = code;
|
|
@@ -125,7 +127,7 @@ function formatRuntimeError(code, message) {
|
|
|
125
127
|
// generate a link to the error details page on angular.io.
|
|
126
128
|
// We also prepend `0` to non-compile-time errors.
|
|
127
129
|
const fullCode = `NG0${Math.abs(code)}`;
|
|
128
|
-
let errorMessage = `${fullCode}${message ? ': ' + message
|
|
130
|
+
let errorMessage = `${fullCode}${message ? ': ' + message : ''}`;
|
|
129
131
|
if (false) {
|
|
130
132
|
}
|
|
131
133
|
return errorMessage;
|
|
@@ -195,9 +197,36 @@ const __forward_ref__ = getClosureSafeProperty({
|
|
|
195
197
|
* DI is declared, but not yet defined. It is also used when the `token` which we use when creating
|
|
196
198
|
* a query is not yet defined.
|
|
197
199
|
*
|
|
200
|
+
* `forwardRef` is also used to break circularities in standalone components imports.
|
|
201
|
+
*
|
|
198
202
|
* @usageNotes
|
|
199
|
-
* ###
|
|
203
|
+
* ### Circular dependency example
|
|
200
204
|
* {@example core/di/ts/forward_ref/forward_ref_spec.ts region='forward_ref'}
|
|
205
|
+
*
|
|
206
|
+
* ### Circular standalone reference import example
|
|
207
|
+
* ```ts
|
|
208
|
+
* @Component({
|
|
209
|
+
* standalone: true,
|
|
210
|
+
* imports: [ChildComponent],
|
|
211
|
+
* selector: 'app-parent',
|
|
212
|
+
* template: `<app-child [hideParent]="hideParent"></app-child>`,
|
|
213
|
+
* })
|
|
214
|
+
* export class ParentComponent {
|
|
215
|
+
* @Input() hideParent: boolean;
|
|
216
|
+
* }
|
|
217
|
+
*
|
|
218
|
+
*
|
|
219
|
+
* @Component({
|
|
220
|
+
* standalone: true,
|
|
221
|
+
* imports: [CommonModule, forwardRef(() => ParentComponent)],
|
|
222
|
+
* selector: 'app-child',
|
|
223
|
+
* template: `<app-parent *ngIf="!hideParent"></app-parent>`,
|
|
224
|
+
* })
|
|
225
|
+
* export class ChildComponent {
|
|
226
|
+
* @Input() hideParent: boolean;
|
|
227
|
+
* }
|
|
228
|
+
* ```
|
|
229
|
+
*
|
|
201
230
|
* @publicApi
|
|
202
231
|
*/
|
|
203
232
|
function forwardRef(forwardRefFn) {
|
|
@@ -217,7 +246,7 @@ function forwardRef(forwardRefFn) {
|
|
|
217
246
|
*
|
|
218
247
|
* {@example core/di/ts/forward_ref/forward_ref_spec.ts region='resolve_forward_ref'}
|
|
219
248
|
*
|
|
220
|
-
* @see
|
|
249
|
+
* @see {@link forwardRef}
|
|
221
250
|
* @publicApi
|
|
222
251
|
*/
|
|
223
252
|
function resolveForwardRef(type) {
|
|
@@ -262,7 +291,8 @@ function throwProviderNotFoundError(token, injectorName) {
|
|
|
262
291
|
* with an `@NgModule` or other `InjectorType`, or by specifying that this injectable should be
|
|
263
292
|
* provided in the `'root'` injector, which will be the application-level injector in most apps.
|
|
264
293
|
* * `factory` gives the zero argument function which will create an instance of the injectable.
|
|
265
|
-
* The factory can call `inject` to access the `Injector` and request injection
|
|
294
|
+
* The factory can call [`inject`](api/core/inject) to access the `Injector` and request injection
|
|
295
|
+
* of dependencies.
|
|
266
296
|
*
|
|
267
297
|
* @codeGenApi
|
|
268
298
|
* @publicApi This instruction has been emitted by ViewEngine for some time and is deployed to npm.
|
|
@@ -325,27 +355,12 @@ function getOwnDefinition(type, field) {
|
|
|
325
355
|
function getInheritedInjectableDef(type) {
|
|
326
356
|
const def = type && (type[NG_PROV_DEF] || null);
|
|
327
357
|
if (def) {
|
|
328
|
-
const typeName = getTypeName(type);
|
|
329
358
|
return def;
|
|
330
359
|
}
|
|
331
360
|
else {
|
|
332
361
|
return null;
|
|
333
362
|
}
|
|
334
363
|
}
|
|
335
|
-
/** Gets the name of a type, accounting for some cross-browser differences. */
|
|
336
|
-
function getTypeName(type) {
|
|
337
|
-
// `Function.prototype.name` behaves differently between IE and other browsers. In most browsers
|
|
338
|
-
// it'll always return the name of the function itself, no matter how many other functions it
|
|
339
|
-
// inherits from. On IE the function doesn't have its own `name` property, but it takes it from
|
|
340
|
-
// the lowest level in the prototype chain. E.g. if we have `class Foo extends Parent` most
|
|
341
|
-
// browsers will evaluate `Foo.name` to `Foo` while IE will return `Parent`. We work around
|
|
342
|
-
// the issue by converting the function to a string and parsing its name out that way via a regex.
|
|
343
|
-
if (type.hasOwnProperty('name')) {
|
|
344
|
-
return type.name;
|
|
345
|
-
}
|
|
346
|
-
const match = ('' + type).match(/^function\s*([^\s(]+)/);
|
|
347
|
-
return match === null ? '' : match[1];
|
|
348
|
-
}
|
|
349
364
|
/**
|
|
350
365
|
* Read the injector def type in a way which is immune to accidentally reading inherited value.
|
|
351
366
|
*
|
|
@@ -374,7 +389,7 @@ const NG_INJ_DEF = getClosureSafeProperty({
|
|
|
374
389
|
* Injection flags for DI.
|
|
375
390
|
*
|
|
376
391
|
* @publicApi
|
|
377
|
-
* @deprecated use an options object for `inject` instead.
|
|
392
|
+
* @deprecated use an options object for [`inject`](api/core/inject) instead.
|
|
378
393
|
*/
|
|
379
394
|
exports.InjectFlags = void 0;
|
|
380
395
|
(function (InjectFlags) {
|
|
@@ -466,6 +481,9 @@ const SOURCE = '__source';
|
|
|
466
481
|
* - Injector instance: Use the injector for resolution.
|
|
467
482
|
*/
|
|
468
483
|
let _currentInjector = undefined;
|
|
484
|
+
function getCurrentInjector() {
|
|
485
|
+
return _currentInjector;
|
|
486
|
+
}
|
|
469
487
|
function setCurrentInjector(injector) {
|
|
470
488
|
const former = _currentInjector;
|
|
471
489
|
_currentInjector = injector;
|
|
@@ -479,7 +497,8 @@ function injectInjectorOnly(token, flags = exports.InjectFlags.Default) {
|
|
|
479
497
|
return injectRootLimpMode(token, undefined, flags);
|
|
480
498
|
}
|
|
481
499
|
else {
|
|
482
|
-
|
|
500
|
+
const value = _currentInjector.get(token, flags & exports.InjectFlags.Optional ? null : undefined, flags);
|
|
501
|
+
return value;
|
|
483
502
|
}
|
|
484
503
|
}
|
|
485
504
|
function ɵɵinject(token, flags = exports.InjectFlags.Default) {
|
|
@@ -499,13 +518,14 @@ function ɵɵinvalidFactoryDep(index) {
|
|
|
499
518
|
}
|
|
500
519
|
/**
|
|
501
520
|
* Injects a token from the currently active injector.
|
|
502
|
-
* `inject` is only supported
|
|
503
|
-
* during:
|
|
521
|
+
* `inject` is only supported in an [injection context](/guide/dependency-injection-context). It can
|
|
522
|
+
* be used during:
|
|
504
523
|
* - Construction (via the `constructor`) of a class being instantiated by the DI system, such
|
|
505
524
|
* as an `@Injectable` or `@Component`.
|
|
506
525
|
* - In the initializer for fields of such classes.
|
|
507
526
|
* - In the factory function specified for `useFactory` of a `Provider` or an `@Injectable`.
|
|
508
527
|
* - In the `factory` function specified for an `InjectionToken`.
|
|
528
|
+
* - In a stackframe of a function call in a DI context
|
|
509
529
|
*
|
|
510
530
|
* @param token A token that represents a dependency that should be injected.
|
|
511
531
|
* @param flags Optional flags that control how injection is executed.
|
|
@@ -730,6 +750,17 @@ attachInjectFlag(makeParamDecorator('SkipSelf'), 4 /* InternalInjectFlags.SkipSe
|
|
|
730
750
|
const NG_FACTORY_DEF = getClosureSafeProperty({
|
|
731
751
|
ɵfac: getClosureSafeProperty,
|
|
732
752
|
});
|
|
753
|
+
/**
|
|
754
|
+
* The `NG_ENV_ID` field on a DI token indicates special processing in the `EnvironmentInjector`:
|
|
755
|
+
* getting such tokens from the `EnvironmentInjector` will bypass the standard DI resolution
|
|
756
|
+
* strategy and instead will return implementation produced by the `NG_ENV_ID` factory function.
|
|
757
|
+
*
|
|
758
|
+
* This particular retrieval of DI tokens is mostly done to eliminate circular dependencies and
|
|
759
|
+
* improve tree-shaking.
|
|
760
|
+
*/
|
|
761
|
+
const NG_ENV_ID = getClosureSafeProperty({
|
|
762
|
+
__NG_ENV_ID__: getClosureSafeProperty,
|
|
763
|
+
});
|
|
733
764
|
|
|
734
765
|
/**
|
|
735
766
|
* @license
|
|
@@ -802,7 +833,7 @@ if (false) {
|
|
|
802
833
|
* (possibly by creating) a default value of the parameterized type `T`. This sets up the
|
|
803
834
|
* `InjectionToken` using this factory as a provider as if it was defined explicitly in the
|
|
804
835
|
* application's root injector. If the factory function, which takes zero arguments, needs to inject
|
|
805
|
-
* dependencies, it can do so using the `inject` function.
|
|
836
|
+
* dependencies, it can do so using the [`inject`](api/core/inject) function.
|
|
806
837
|
* As you can see in the Tree-shakable InjectionToken example below.
|
|
807
838
|
*
|
|
808
839
|
* Additionally, if a `factory` is specified you can also specify the `providedIn` option, which
|
|
@@ -827,6 +858,10 @@ if (false) {
|
|
|
827
858
|
* @publicApi
|
|
828
859
|
*/
|
|
829
860
|
class InjectionToken {
|
|
861
|
+
_desc;
|
|
862
|
+
/** @internal */
|
|
863
|
+
ngMetadataName = 'InjectionToken';
|
|
864
|
+
ɵprov;
|
|
830
865
|
/**
|
|
831
866
|
* @param _desc Description for the token,
|
|
832
867
|
* used only for debugging purposes,
|
|
@@ -835,8 +870,6 @@ class InjectionToken {
|
|
|
835
870
|
*/
|
|
836
871
|
constructor(_desc, options) {
|
|
837
872
|
this._desc = _desc;
|
|
838
|
-
/** @internal */
|
|
839
|
-
this.ngMetadataName = 'InjectionToken';
|
|
840
873
|
this.ɵprov = undefined;
|
|
841
874
|
if (typeof options == 'number') {
|
|
842
875
|
}
|
|
@@ -942,7 +975,7 @@ class NullInjector {
|
|
|
942
975
|
*/
|
|
943
976
|
/**
|
|
944
977
|
* Wrap an array of `Provider`s into `EnvironmentProviders`, preventing them from being accidentally
|
|
945
|
-
* referenced in `@Component in a component injector.
|
|
978
|
+
* referenced in `@Component` in a component injector.
|
|
946
979
|
*/
|
|
947
980
|
function makeEnvironmentProviders(providers) {
|
|
948
981
|
return {
|
|
@@ -999,9 +1032,12 @@ function internalImportProvidersFrom(checkForStandaloneCmp, ...sources) {
|
|
|
999
1032
|
const providersOut = [];
|
|
1000
1033
|
const dedup = new Set(); // already seen types
|
|
1001
1034
|
let injectorTypesWithProviders;
|
|
1035
|
+
const collectProviders = (provider) => {
|
|
1036
|
+
providersOut.push(provider);
|
|
1037
|
+
};
|
|
1002
1038
|
// Collect all providers from `ModuleWithProviders` types.
|
|
1003
1039
|
if (injectorTypesWithProviders !== undefined) {
|
|
1004
|
-
processInjectorTypesWithProviders(injectorTypesWithProviders,
|
|
1040
|
+
processInjectorTypesWithProviders(injectorTypesWithProviders, collectProviders);
|
|
1005
1041
|
}
|
|
1006
1042
|
return providersOut;
|
|
1007
1043
|
}
|
|
@@ -1009,145 +1045,11 @@ function internalImportProvidersFrom(checkForStandaloneCmp, ...sources) {
|
|
|
1009
1045
|
* Collects all providers from the list of `ModuleWithProviders` and appends them to the provided
|
|
1010
1046
|
* array.
|
|
1011
1047
|
*/
|
|
1012
|
-
function processInjectorTypesWithProviders(typesWithProviders,
|
|
1048
|
+
function processInjectorTypesWithProviders(typesWithProviders, visitor) {
|
|
1013
1049
|
for (let i = 0; i < typesWithProviders.length; i++) {
|
|
1014
1050
|
const { ngModule, providers } = typesWithProviders[i];
|
|
1015
1051
|
}
|
|
1016
1052
|
}
|
|
1017
|
-
/**
|
|
1018
|
-
* The logic visits an `InjectorType`, an `InjectorTypeWithProviders`, or a standalone
|
|
1019
|
-
* `ComponentType`, and all of its transitive providers and collects providers.
|
|
1020
|
-
*
|
|
1021
|
-
* If an `InjectorTypeWithProviders` that declares providers besides the type is specified,
|
|
1022
|
-
* the function will return "true" to indicate that the providers of the type definition need
|
|
1023
|
-
* to be processed. This allows us to process providers of injector types after all imports of
|
|
1024
|
-
* an injector definition are processed. (following View Engine semantics: see FW-1349)
|
|
1025
|
-
*/
|
|
1026
|
-
function walkProviderTree(container, providersOut, parents, dedup) {
|
|
1027
|
-
container = resolveForwardRef(container);
|
|
1028
|
-
if (!container)
|
|
1029
|
-
return false;
|
|
1030
|
-
// The actual type which had the definition. Usually `container`, but may be an unwrapped type
|
|
1031
|
-
// from `InjectorTypeWithProviders`.
|
|
1032
|
-
let defType = null;
|
|
1033
|
-
let injDef = getInjectorDef(container);
|
|
1034
|
-
const cmpDef = !injDef && null;
|
|
1035
|
-
if (!injDef && !cmpDef) {
|
|
1036
|
-
// `container` is not an injector type or a component type. It might be:
|
|
1037
|
-
// * An `InjectorTypeWithProviders` that wraps an injector type.
|
|
1038
|
-
// * A standalone directive or pipe that got pulled in from a standalone component's
|
|
1039
|
-
// dependencies.
|
|
1040
|
-
// Try to unwrap it as an `InjectorTypeWithProviders` first.
|
|
1041
|
-
const ngModule = container.ngModule;
|
|
1042
|
-
injDef = getInjectorDef(ngModule);
|
|
1043
|
-
if (injDef) {
|
|
1044
|
-
defType = ngModule;
|
|
1045
|
-
}
|
|
1046
|
-
else {
|
|
1047
|
-
// Not a component or injector type, so ignore it.
|
|
1048
|
-
return false;
|
|
1049
|
-
}
|
|
1050
|
-
}
|
|
1051
|
-
else if (cmpDef && !cmpDef.standalone) {
|
|
1052
|
-
return false;
|
|
1053
|
-
}
|
|
1054
|
-
else {
|
|
1055
|
-
defType = container;
|
|
1056
|
-
}
|
|
1057
|
-
// Check for circular dependencies.
|
|
1058
|
-
if (false) {
|
|
1059
|
-
}
|
|
1060
|
-
// Check for multiple imports of the same module
|
|
1061
|
-
const isDuplicate = dedup.has(defType);
|
|
1062
|
-
if (cmpDef) {
|
|
1063
|
-
if (isDuplicate) {
|
|
1064
|
-
// This component definition has already been processed.
|
|
1065
|
-
return false;
|
|
1066
|
-
}
|
|
1067
|
-
dedup.add(defType);
|
|
1068
|
-
if (cmpDef.dependencies) {
|
|
1069
|
-
const deps = typeof cmpDef.dependencies === 'function'
|
|
1070
|
-
? cmpDef.dependencies()
|
|
1071
|
-
: cmpDef.dependencies;
|
|
1072
|
-
for (const dep of deps) {
|
|
1073
|
-
walkProviderTree(dep, providersOut, parents, dedup);
|
|
1074
|
-
}
|
|
1075
|
-
}
|
|
1076
|
-
}
|
|
1077
|
-
else if (injDef) {
|
|
1078
|
-
// First, include providers from any imports.
|
|
1079
|
-
if (injDef.imports != null && !isDuplicate) {
|
|
1080
|
-
// Before processing defType's imports, add it to the set of parents. This way, if it ends
|
|
1081
|
-
// up deeply importing itself, this can be detected.
|
|
1082
|
-
// Add it to the set of dedups. This way we can detect multiple imports of the same module
|
|
1083
|
-
dedup.add(defType);
|
|
1084
|
-
let importTypesWithProviders;
|
|
1085
|
-
try {
|
|
1086
|
-
deepForEach(injDef.imports, (imported) => {
|
|
1087
|
-
if (walkProviderTree(imported, providersOut, parents, dedup)) {
|
|
1088
|
-
importTypesWithProviders || (importTypesWithProviders = []);
|
|
1089
|
-
// If the processed import is an injector type with providers, we store it in the
|
|
1090
|
-
// list of import types with providers, so that we can process those afterwards.
|
|
1091
|
-
importTypesWithProviders.push(imported);
|
|
1092
|
-
}
|
|
1093
|
-
});
|
|
1094
|
-
}
|
|
1095
|
-
finally {
|
|
1096
|
-
// Remove it from the parents set when finished.
|
|
1097
|
-
}
|
|
1098
|
-
// Imports which are declared with providers (TypeWithProviders) need to be processed
|
|
1099
|
-
// after all imported modules are processed. This is similar to how View Engine
|
|
1100
|
-
// processes/merges module imports in the metadata resolver. See: FW-1349.
|
|
1101
|
-
if (importTypesWithProviders !== undefined) {
|
|
1102
|
-
processInjectorTypesWithProviders(importTypesWithProviders, providersOut);
|
|
1103
|
-
}
|
|
1104
|
-
}
|
|
1105
|
-
if (!isDuplicate) {
|
|
1106
|
-
// Track the InjectorType and add a provider for it.
|
|
1107
|
-
// It's important that this is done after the def's imports.
|
|
1108
|
-
const factory = getFactoryDef(defType) || (() => new defType());
|
|
1109
|
-
// Append extra providers to make more info available for consumers (to retrieve an injector
|
|
1110
|
-
// type), as well as internally (to calculate an injection scope correctly and eagerly
|
|
1111
|
-
// instantiate a `defType` when an injector is created).
|
|
1112
|
-
providersOut.push(
|
|
1113
|
-
// Provider to create `defType` using its factory.
|
|
1114
|
-
{ provide: defType, useFactory: factory, deps: EMPTY_ARRAY },
|
|
1115
|
-
// Make this `defType` available to an internal logic that calculates injector scope.
|
|
1116
|
-
{ provide: INJECTOR_DEF_TYPES, useValue: defType, multi: true },
|
|
1117
|
-
// Provider to eagerly instantiate `defType` via `ENVIRONMENT_INITIALIZER`.
|
|
1118
|
-
{
|
|
1119
|
-
provide: ENVIRONMENT_INITIALIZER,
|
|
1120
|
-
useValue: () => ɵɵinject(defType),
|
|
1121
|
-
multi: true,
|
|
1122
|
-
} //
|
|
1123
|
-
);
|
|
1124
|
-
}
|
|
1125
|
-
// Next, include providers listed on the definition itself.
|
|
1126
|
-
const defProviders = injDef.providers;
|
|
1127
|
-
if (defProviders != null && !isDuplicate) {
|
|
1128
|
-
const injectorType = container;
|
|
1129
|
-
}
|
|
1130
|
-
}
|
|
1131
|
-
else {
|
|
1132
|
-
// Should not happen, but just in case.
|
|
1133
|
-
return false;
|
|
1134
|
-
}
|
|
1135
|
-
return (defType !== container &&
|
|
1136
|
-
container.providers !== undefined);
|
|
1137
|
-
}
|
|
1138
|
-
function deepForEachProvider(providers, fn) {
|
|
1139
|
-
for (let provider of providers) {
|
|
1140
|
-
if (isEnvironmentProviders(provider)) {
|
|
1141
|
-
provider = provider.ɵproviders;
|
|
1142
|
-
}
|
|
1143
|
-
if (Array.isArray(provider)) {
|
|
1144
|
-
deepForEachProvider(provider, fn);
|
|
1145
|
-
}
|
|
1146
|
-
else {
|
|
1147
|
-
fn(provider);
|
|
1148
|
-
}
|
|
1149
|
-
}
|
|
1150
|
-
}
|
|
1151
1053
|
const USE_VALUE = getClosureSafeProperty({
|
|
1152
1054
|
provide: String,
|
|
1153
1055
|
useValue: getClosureSafeProperty,
|
|
@@ -1218,29 +1120,33 @@ function getNullInjector() {
|
|
|
1218
1120
|
class EnvironmentInjector {
|
|
1219
1121
|
}
|
|
1220
1122
|
class R3Injector extends EnvironmentInjector {
|
|
1123
|
+
parent;
|
|
1124
|
+
source;
|
|
1125
|
+
scopes;
|
|
1126
|
+
/**
|
|
1127
|
+
* Map of tokens to records which contain the instances of those tokens.
|
|
1128
|
+
* - `null` value implies that we don't have the record. Used by tree-shakable injectors
|
|
1129
|
+
* to prevent further searches.
|
|
1130
|
+
*/
|
|
1131
|
+
records = new Map();
|
|
1132
|
+
/**
|
|
1133
|
+
* Set of values instantiated by this injector which contain `ngOnDestroy` lifecycle hooks.
|
|
1134
|
+
*/
|
|
1135
|
+
_ngOnDestroyHooks = new Set();
|
|
1136
|
+
_onDestroyHooks = [];
|
|
1221
1137
|
/**
|
|
1222
1138
|
* Flag indicating that this injector was previously destroyed.
|
|
1223
1139
|
*/
|
|
1224
1140
|
get destroyed() {
|
|
1225
1141
|
return this._destroyed;
|
|
1226
1142
|
}
|
|
1143
|
+
_destroyed = false;
|
|
1144
|
+
injectorDefTypes;
|
|
1227
1145
|
constructor(providers, parent, source, scopes) {
|
|
1228
1146
|
super();
|
|
1229
1147
|
this.parent = parent;
|
|
1230
1148
|
this.source = source;
|
|
1231
1149
|
this.scopes = scopes;
|
|
1232
|
-
/**
|
|
1233
|
-
* Map of tokens to records which contain the instances of those tokens.
|
|
1234
|
-
* - `null` value implies that we don't have the record. Used by tree-shakable injectors
|
|
1235
|
-
* to prevent further searches.
|
|
1236
|
-
*/
|
|
1237
|
-
this.records = new Map();
|
|
1238
|
-
/**
|
|
1239
|
-
* Set of values instantiated by this injector which contain `ngOnDestroy` lifecycle hooks.
|
|
1240
|
-
*/
|
|
1241
|
-
this._ngOnDestroyHooks = new Set();
|
|
1242
|
-
this._onDestroyHooks = [];
|
|
1243
|
-
this._destroyed = false;
|
|
1244
1150
|
// Start off by creating Records for every provider.
|
|
1245
1151
|
forEachSingleProvider(providers, (provider) => this.processProvider(provider));
|
|
1246
1152
|
// Make sure the INJECTOR token provides this injector.
|
|
@@ -1272,7 +1178,11 @@ class R3Injector extends EnvironmentInjector {
|
|
|
1272
1178
|
for (const service of this._ngOnDestroyHooks) {
|
|
1273
1179
|
service.ngOnDestroy();
|
|
1274
1180
|
}
|
|
1275
|
-
|
|
1181
|
+
const onDestroyHooks = this._onDestroyHooks;
|
|
1182
|
+
// Reset the _onDestroyHooks array before iterating over it to prevent hooks that unregister
|
|
1183
|
+
// themselves from mutating the array during iteration.
|
|
1184
|
+
this._onDestroyHooks = [];
|
|
1185
|
+
for (const hook of onDestroyHooks) {
|
|
1276
1186
|
hook();
|
|
1277
1187
|
}
|
|
1278
1188
|
}
|
|
@@ -1281,16 +1191,19 @@ class R3Injector extends EnvironmentInjector {
|
|
|
1281
1191
|
this.records.clear();
|
|
1282
1192
|
this._ngOnDestroyHooks.clear();
|
|
1283
1193
|
this.injectorDefTypes.clear();
|
|
1284
|
-
this._onDestroyHooks.length = 0;
|
|
1285
1194
|
}
|
|
1286
1195
|
}
|
|
1287
1196
|
onDestroy(callback) {
|
|
1197
|
+
this.assertNotDestroyed();
|
|
1288
1198
|
this._onDestroyHooks.push(callback);
|
|
1199
|
+
return () => this.removeOnDestroy(callback);
|
|
1289
1200
|
}
|
|
1290
1201
|
runInContext(fn) {
|
|
1291
1202
|
this.assertNotDestroyed();
|
|
1292
1203
|
const previousInjector = setCurrentInjector(this);
|
|
1293
1204
|
const previousInjectImplementation = setInjectImplementation(undefined);
|
|
1205
|
+
if (false) {
|
|
1206
|
+
}
|
|
1294
1207
|
try {
|
|
1295
1208
|
return fn();
|
|
1296
1209
|
}
|
|
@@ -1301,8 +1214,13 @@ class R3Injector extends EnvironmentInjector {
|
|
|
1301
1214
|
}
|
|
1302
1215
|
get(token, notFoundValue = THROW_IF_NOT_FOUND, flags = exports.InjectFlags.Default) {
|
|
1303
1216
|
this.assertNotDestroyed();
|
|
1217
|
+
if (token.hasOwnProperty(NG_ENV_ID)) {
|
|
1218
|
+
return token[NG_ENV_ID](this);
|
|
1219
|
+
}
|
|
1304
1220
|
flags = convertToBitFlags(flags);
|
|
1305
1221
|
// Set the injection context.
|
|
1222
|
+
if (false) {
|
|
1223
|
+
}
|
|
1306
1224
|
const previousInjector = setCurrentInjector(this);
|
|
1307
1225
|
const previousInjectImplementation = setInjectImplementation(undefined);
|
|
1308
1226
|
try {
|
|
@@ -1370,6 +1288,8 @@ class R3Injector extends EnvironmentInjector {
|
|
|
1370
1288
|
resolveInjectorInitializers() {
|
|
1371
1289
|
const previousInjector = setCurrentInjector(this);
|
|
1372
1290
|
const previousInjectImplementation = setInjectImplementation(undefined);
|
|
1291
|
+
if (false) {
|
|
1292
|
+
}
|
|
1373
1293
|
try {
|
|
1374
1294
|
const initializers = this.get(ENVIRONMENT_INITIALIZER.multi, EMPTY_ARRAY, exports.InjectFlags.Self);
|
|
1375
1295
|
if (false) {
|
|
@@ -1408,6 +1328,8 @@ class R3Injector extends EnvironmentInjector {
|
|
|
1408
1328
|
: resolveForwardRef(provider && provider.provide);
|
|
1409
1329
|
// Construct a `Record` for the provider.
|
|
1410
1330
|
const record = providerToRecord(provider);
|
|
1331
|
+
if (false) {
|
|
1332
|
+
}
|
|
1411
1333
|
if (!isTypeProvider(provider) && provider.multi === true) {
|
|
1412
1334
|
// If the provider indicates that it's a multi-provider, process it specially.
|
|
1413
1335
|
// First check whether it's been defined already.
|
|
@@ -1437,7 +1359,11 @@ class R3Injector extends EnvironmentInjector {
|
|
|
1437
1359
|
}
|
|
1438
1360
|
else if (record.value === NOT_YET) {
|
|
1439
1361
|
record.value = CIRCULAR;
|
|
1440
|
-
|
|
1362
|
+
if (false) {
|
|
1363
|
+
}
|
|
1364
|
+
else {
|
|
1365
|
+
record.value = record.factory();
|
|
1366
|
+
}
|
|
1441
1367
|
}
|
|
1442
1368
|
if (typeof record.value === 'object' &&
|
|
1443
1369
|
record.value &&
|
|
@@ -1458,6 +1384,12 @@ class R3Injector extends EnvironmentInjector {
|
|
|
1458
1384
|
return this.injectorDefTypes.has(providedIn);
|
|
1459
1385
|
}
|
|
1460
1386
|
}
|
|
1387
|
+
removeOnDestroy(callback) {
|
|
1388
|
+
const destroyCBIdx = this._onDestroyHooks.indexOf(callback);
|
|
1389
|
+
if (destroyCBIdx !== -1) {
|
|
1390
|
+
this._onDestroyHooks.splice(destroyCBIdx, 1);
|
|
1391
|
+
}
|
|
1392
|
+
}
|
|
1461
1393
|
}
|
|
1462
1394
|
function injectableDefOrInjectorDefFactory(token) {
|
|
1463
1395
|
// Most tokens will have an injectable def directly on them, which specifies a factory directly.
|
|
@@ -1589,8 +1521,6 @@ function forEachSingleProvider(providers, fn) {
|
|
|
1589
1521
|
*/
|
|
1590
1522
|
/**
|
|
1591
1523
|
* Create a new `Injector` which is configured using a `defType` of `InjectorType<any>`s.
|
|
1592
|
-
*
|
|
1593
|
-
* @publicApi
|
|
1594
1524
|
*/
|
|
1595
1525
|
function createInjector(defType, parent = null, additionalProviders = null, name) {
|
|
1596
1526
|
const injector = createInjectorWithoutInjectorInstances(defType, parent, additionalProviders, name);
|
|
@@ -1624,7 +1554,7 @@ function createInjectorWithoutInjectorInstances(defType, parent = null, addition
|
|
|
1624
1554
|
* dependencies of various types with [injection tokens](guide/glossary#di-token).
|
|
1625
1555
|
*
|
|
1626
1556
|
* @see ["DI Providers"](guide/dependency-injection-providers).
|
|
1627
|
-
* @see
|
|
1557
|
+
* @see {@link StaticProvider}
|
|
1628
1558
|
*
|
|
1629
1559
|
* @usageNotes
|
|
1630
1560
|
*
|
|
@@ -1643,30 +1573,29 @@ function createInjectorWithoutInjectorInstances(defType, parent = null, addition
|
|
|
1643
1573
|
* @publicApi
|
|
1644
1574
|
*/
|
|
1645
1575
|
class Injector {
|
|
1576
|
+
static THROW_IF_NOT_FOUND = THROW_IF_NOT_FOUND;
|
|
1577
|
+
static NULL = new NullInjector();
|
|
1646
1578
|
static create(options, parent) {
|
|
1647
|
-
var _a;
|
|
1648
1579
|
if (Array.isArray(options)) {
|
|
1649
1580
|
return createInjector({ name: '' }, parent, options, '');
|
|
1650
1581
|
}
|
|
1651
1582
|
else {
|
|
1652
|
-
const name =
|
|
1583
|
+
const name = options.name ?? '';
|
|
1653
1584
|
return createInjector({ name }, options.parent, options.providers, name);
|
|
1654
1585
|
}
|
|
1655
1586
|
}
|
|
1587
|
+
/** @nocollapse */
|
|
1588
|
+
static ɵprov = /** @pureOrBreakMyCode */ ɵɵdefineInjectable({
|
|
1589
|
+
token: Injector,
|
|
1590
|
+
providedIn: 'any',
|
|
1591
|
+
factory: () => ɵɵinject(INJECTOR),
|
|
1592
|
+
});
|
|
1593
|
+
/**
|
|
1594
|
+
* @internal
|
|
1595
|
+
* @nocollapse
|
|
1596
|
+
*/
|
|
1597
|
+
static __NG_ELEMENT_ID__ = -1 /* InjectorMarkers.Injector */;
|
|
1656
1598
|
}
|
|
1657
|
-
Injector.THROW_IF_NOT_FOUND = THROW_IF_NOT_FOUND;
|
|
1658
|
-
Injector.NULL = new NullInjector();
|
|
1659
|
-
/** @nocollapse */
|
|
1660
|
-
Injector.ɵprov = ɵɵdefineInjectable({
|
|
1661
|
-
token: Injector,
|
|
1662
|
-
providedIn: 'any',
|
|
1663
|
-
factory: () => ɵɵinject(INJECTOR),
|
|
1664
|
-
});
|
|
1665
|
-
/**
|
|
1666
|
-
* @internal
|
|
1667
|
-
* @nocollapse
|
|
1668
|
-
*/
|
|
1669
|
-
Injector.__NG_ELEMENT_ID__ = -1 /* InjectorMarkers.Injector */;
|
|
1670
1599
|
|
|
1671
1600
|
/**
|
|
1672
1601
|
* Throws an error indicating that a factory function could not be generated by the compiler for a
|
|
@@ -1751,6 +1680,7 @@ exports.attachInjectFlag = attachInjectFlag;
|
|
|
1751
1680
|
exports.catchInjectorError = catchInjectorError;
|
|
1752
1681
|
exports.convertToBitFlags = convertToBitFlags;
|
|
1753
1682
|
exports.formatError = formatError;
|
|
1683
|
+
exports.getCurrentInjector = getCurrentInjector;
|
|
1754
1684
|
exports.getInheritedInjectableDef = getInheritedInjectableDef;
|
|
1755
1685
|
exports.getInjectFlag = getInjectFlag;
|
|
1756
1686
|
exports.getInjectableDef = getInjectableDef;
|
|
@@ -11,8 +11,6 @@ import { importProvidersFrom } from './provider_collection';
|
|
|
11
11
|
import { getNullInjector, R3Injector } from './r3_injector';
|
|
12
12
|
/**
|
|
13
13
|
* Create a new `Injector` which is configured using a `defType` of `InjectorType<any>`s.
|
|
14
|
-
*
|
|
15
|
-
* @publicApi
|
|
16
14
|
*/
|
|
17
15
|
export function createInjector(defType, parent = null, additionalProviders = null, name) {
|
|
18
16
|
const injector = createInjectorWithoutInjectorInstances(defType, parent, additionalProviders, name);
|
|
@@ -17,9 +17,36 @@ const __forward_ref__ = getClosureSafeProperty({
|
|
|
17
17
|
* DI is declared, but not yet defined. It is also used when the `token` which we use when creating
|
|
18
18
|
* a query is not yet defined.
|
|
19
19
|
*
|
|
20
|
+
* `forwardRef` is also used to break circularities in standalone components imports.
|
|
21
|
+
*
|
|
20
22
|
* @usageNotes
|
|
21
|
-
* ###
|
|
23
|
+
* ### Circular dependency example
|
|
22
24
|
* {@example core/di/ts/forward_ref/forward_ref_spec.ts region='forward_ref'}
|
|
25
|
+
*
|
|
26
|
+
* ### Circular standalone reference import example
|
|
27
|
+
* ```ts
|
|
28
|
+
* @Component({
|
|
29
|
+
* standalone: true,
|
|
30
|
+
* imports: [ChildComponent],
|
|
31
|
+
* selector: 'app-parent',
|
|
32
|
+
* template: `<app-child [hideParent]="hideParent"></app-child>`,
|
|
33
|
+
* })
|
|
34
|
+
* export class ParentComponent {
|
|
35
|
+
* @Input() hideParent: boolean;
|
|
36
|
+
* }
|
|
37
|
+
*
|
|
38
|
+
*
|
|
39
|
+
* @Component({
|
|
40
|
+
* standalone: true,
|
|
41
|
+
* imports: [CommonModule, forwardRef(() => ParentComponent)],
|
|
42
|
+
* selector: 'app-child',
|
|
43
|
+
* template: `<app-parent *ngIf="!hideParent"></app-parent>`,
|
|
44
|
+
* })
|
|
45
|
+
* export class ChildComponent {
|
|
46
|
+
* @Input() hideParent: boolean;
|
|
47
|
+
* }
|
|
48
|
+
* ```
|
|
49
|
+
*
|
|
23
50
|
* @publicApi
|
|
24
51
|
*/
|
|
25
52
|
export function forwardRef(forwardRefFn) {
|
|
@@ -39,7 +66,7 @@ export function forwardRef(forwardRefFn) {
|
|
|
39
66
|
*
|
|
40
67
|
* {@example core/di/ts/forward_ref/forward_ref_spec.ts region='resolve_forward_ref'}
|
|
41
68
|
*
|
|
42
|
-
* @see
|
|
69
|
+
* @see {@link forwardRef}
|
|
43
70
|
* @publicApi
|
|
44
71
|
*/
|
|
45
72
|
export function resolveForwardRef(type) {
|
|
@@ -26,7 +26,7 @@ import { ɵɵdefineInjectable } from './interface/defs';
|
|
|
26
26
|
* (possibly by creating) a default value of the parameterized type `T`. This sets up the
|
|
27
27
|
* `InjectionToken` using this factory as a provider as if it was defined explicitly in the
|
|
28
28
|
* application's root injector. If the factory function, which takes zero arguments, needs to inject
|
|
29
|
-
* dependencies, it can do so using the `inject` function.
|
|
29
|
+
* dependencies, it can do so using the [`inject`](api/core/inject) function.
|
|
30
30
|
* As you can see in the Tree-shakable InjectionToken example below.
|
|
31
31
|
*
|
|
32
32
|
* Additionally, if a `factory` is specified you can also specify the `providedIn` option, which
|
|
@@ -51,6 +51,10 @@ import { ɵɵdefineInjectable } from './interface/defs';
|
|
|
51
51
|
* @publicApi
|
|
52
52
|
*/
|
|
53
53
|
export class InjectionToken {
|
|
54
|
+
_desc;
|
|
55
|
+
/** @internal */
|
|
56
|
+
ngMetadataName = 'InjectionToken';
|
|
57
|
+
ɵprov;
|
|
54
58
|
/**
|
|
55
59
|
* @param _desc Description for the token,
|
|
56
60
|
* used only for debugging purposes,
|
|
@@ -59,8 +63,6 @@ export class InjectionToken {
|
|
|
59
63
|
*/
|
|
60
64
|
constructor(_desc, options) {
|
|
61
65
|
this._desc = _desc;
|
|
62
|
-
/** @internal */
|
|
63
|
-
this.ngMetadataName = 'InjectionToken';
|
|
64
66
|
this.ɵprov = undefined;
|
|
65
67
|
if (typeof options == 'number') {
|
|
66
68
|
}
|