@codefast/di 0.3.16-canary.3 → 0.4.0-canary.5
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/CHANGELOG.md +10 -0
- package/README.md +5 -17
- package/dist/container.d.mts +3 -3
- package/dist/container.mjs +7 -7
- package/dist/decorators/inject.mjs +2 -2
- package/dist/decorators/lifecycle-decorators.mjs +2 -2
- package/dist/dependency-graph.d.mts +1 -1
- package/dist/index.d.mts +3 -3
- package/dist/index.mjs +1 -1
- package/dist/module.mjs +1 -1
- package/dist/resolver.d.mts +1 -1
- package/package.json +8 -8
- package/src/binding-select.ts +4 -13
- package/src/binding.ts +3 -7
- package/src/constraints.ts +16 -44
- package/src/container.ts +63 -141
- package/src/decorators/inject.ts +11 -22
- package/src/decorators/injectable.ts +2 -2
- package/src/decorators/lifecycle-decorators.ts +4 -8
- package/src/dependency-graph.ts +3 -3
- package/src/environment.ts +9 -34
- package/src/errors.ts +1 -3
- package/src/inspector.ts +9 -17
- package/src/lifecycle.ts +9 -30
- package/src/metadata/metadata-reader-token.ts +1 -1
- package/src/metadata/metadata-types.ts +3 -5
- package/src/metadata/symbol-metadata-reader.ts +4 -16
- package/src/module.ts +2 -2
- package/src/registry.ts +5 -14
- package/src/resolver.ts +76 -304
- package/src/scope.ts +1 -1
- package/src/types.ts +7 -29
package/src/resolver.ts
CHANGED
|
@@ -1,21 +1,10 @@
|
|
|
1
|
-
import type { ConstructorInvocation } from "#/constructor-type";
|
|
2
|
-
import type {
|
|
3
|
-
BindingIdentifier,
|
|
4
|
-
BindingScope,
|
|
5
|
-
BindingTag,
|
|
6
|
-
ConstraintContext,
|
|
7
|
-
Constructor,
|
|
8
|
-
ResolutionFrame,
|
|
9
|
-
ResolveOptions,
|
|
10
|
-
} from "#/types";
|
|
11
|
-
import type { Token } from "#/token";
|
|
12
1
|
import type { Binding, BindingSlot } from "#/binding";
|
|
13
|
-
import
|
|
14
|
-
import type {
|
|
15
|
-
import type { LifecycleManager } from "#/lifecycle";
|
|
16
|
-
import type { ConstructorMetadata, MetadataReader } from "#/metadata/metadata-types";
|
|
17
|
-
import type { InjectionDescriptor } from "#/decorators/inject";
|
|
2
|
+
import { selectAllBindings, selectBinding } from "#/binding-select";
|
|
3
|
+
import type { ConstructorInvocation } from "#/constructor-type";
|
|
18
4
|
import type { Container } from "#/container";
|
|
5
|
+
import type { InjectionDescriptor } from "#/decorators/inject";
|
|
6
|
+
import type { ResolverCallbacks } from "#/environment";
|
|
7
|
+
import { buildResolutionFrame, DefaultResolutionContext, runWithContainer } from "#/environment";
|
|
19
8
|
import {
|
|
20
9
|
AsyncResolutionError,
|
|
21
10
|
CircularDependencyError,
|
|
@@ -25,11 +14,22 @@ import {
|
|
|
25
14
|
NoMatchingBindingError,
|
|
26
15
|
TokenNotBoundError,
|
|
27
16
|
} from "#/errors";
|
|
28
|
-
import {
|
|
29
|
-
import type {
|
|
30
|
-
import {
|
|
17
|
+
import type { LifecycleManager } from "#/lifecycle";
|
|
18
|
+
import type { ConstructorMetadata, MetadataReader } from "#/metadata/metadata-types";
|
|
19
|
+
import type { BindingRegistry } from "#/registry";
|
|
31
20
|
import { injectionSlotToResolveOptions } from "#/resolve-options";
|
|
32
|
-
import {
|
|
21
|
+
import type { ScopeManager } from "#/scope";
|
|
22
|
+
import type { Token } from "#/token";
|
|
23
|
+
import { tokenName } from "#/token";
|
|
24
|
+
import type {
|
|
25
|
+
BindingIdentifier,
|
|
26
|
+
BindingScope,
|
|
27
|
+
BindingTag,
|
|
28
|
+
ConstraintContext,
|
|
29
|
+
Constructor,
|
|
30
|
+
ResolutionFrame,
|
|
31
|
+
ResolveOptions,
|
|
32
|
+
} from "#/types";
|
|
33
33
|
|
|
34
34
|
type BindingWithScope = Binding & { scope: BindingScope };
|
|
35
35
|
const RESOLUTION_SET_KEY: unique symbol = Symbol("di:resolution-set");
|
|
@@ -111,10 +111,7 @@ export class DependencyResolver {
|
|
|
111
111
|
private _deepAsyncActiveLevels = 0;
|
|
112
112
|
private readonly _classHasPostConstruct = new WeakMap<Constructor, boolean>();
|
|
113
113
|
private readonly _classNeedsActiveContainer = new WeakMap<Constructor, boolean>();
|
|
114
|
-
private readonly _classConstructorMetadata = new WeakMap<
|
|
115
|
-
Constructor,
|
|
116
|
-
ConstructorMetadata | null
|
|
117
|
-
>();
|
|
114
|
+
private readonly _classConstructorMetadata = new WeakMap<Constructor, ConstructorMetadata | null>();
|
|
118
115
|
private readonly _activationNeedByBindingId = new Map<BindingIdentifier, boolean>();
|
|
119
116
|
private _activationCacheVersion = -1;
|
|
120
117
|
|
|
@@ -144,20 +141,12 @@ export class DependencyResolver {
|
|
|
144
141
|
|
|
145
142
|
if (hint?.name !== undefined && hint.tag === undefined && (hint.tags?.length ?? 0) === 0) {
|
|
146
143
|
const namedBinding = this._registry.getSimpleNamed(token, hint.name);
|
|
147
|
-
if (
|
|
148
|
-
namedBinding !== undefined &&
|
|
149
|
-
this._matchesBindingFast(namedBinding, hint, resolutionPath, resolutionStack)
|
|
150
|
-
) {
|
|
144
|
+
if (namedBinding !== undefined && this._matchesBindingFast(namedBinding, hint, resolutionPath, resolutionStack)) {
|
|
151
145
|
return { binding: namedBinding, owner: this };
|
|
152
146
|
}
|
|
153
147
|
}
|
|
154
148
|
|
|
155
|
-
if (
|
|
156
|
-
hint !== undefined &&
|
|
157
|
-
hint.name === undefined &&
|
|
158
|
-
hint.tag === undefined &&
|
|
159
|
-
(hint.tags?.length ?? 0) === 1
|
|
160
|
-
) {
|
|
149
|
+
if (hint !== undefined && hint.name === undefined && hint.tag === undefined && (hint.tags?.length ?? 0) === 1) {
|
|
161
150
|
const [tagKey, tagValue] = hint.tags![0]!;
|
|
162
151
|
const tagged = this._registry.getSimpleTagged(token, tagKey, tagValue);
|
|
163
152
|
if (tagged !== undefined) {
|
|
@@ -169,8 +158,7 @@ export class DependencyResolver {
|
|
|
169
158
|
if (bindings.length > 0) {
|
|
170
159
|
if (bindings.length === 1) {
|
|
171
160
|
const onlyBinding = bindings[0]!;
|
|
172
|
-
const isDefaultSlot =
|
|
173
|
-
onlyBinding.slot.name === undefined && onlyBinding.slot.tags.length === 0;
|
|
161
|
+
const isDefaultSlot = onlyBinding.slot.name === undefined && onlyBinding.slot.tags.length === 0;
|
|
174
162
|
if (hint === undefined && isDefaultSlot && onlyBinding.predicate === undefined) {
|
|
175
163
|
return { binding: onlyBinding, owner: this };
|
|
176
164
|
}
|
|
@@ -239,8 +227,7 @@ export class DependencyResolver {
|
|
|
239
227
|
scope === "transient" &&
|
|
240
228
|
fastBinding.kind === "dynamic" &&
|
|
241
229
|
fastBinding.onActivation === undefined &&
|
|
242
|
-
(this._lifecycle.activationVersion === 0 ||
|
|
243
|
-
!this._lifecycle.hasActivationHandlers(fastBinding.token))
|
|
230
|
+
(this._lifecycle.activationVersion === 0 || !this._lifecycle.hasActivationHandlers(fastBinding.token))
|
|
244
231
|
) {
|
|
245
232
|
return this._resolveTransientDynamicSyncFromContext(
|
|
246
233
|
fastBinding as Binding<Value> & { kind: "dynamic" },
|
|
@@ -259,12 +246,7 @@ export class DependencyResolver {
|
|
|
259
246
|
return this._scope.getScoped<Value>(fastBinding.id);
|
|
260
247
|
}
|
|
261
248
|
}
|
|
262
|
-
return this._resolveBinding(
|
|
263
|
-
fastBinding as Binding<Value>,
|
|
264
|
-
undefined,
|
|
265
|
-
resolutionPath,
|
|
266
|
-
resolutionStack,
|
|
267
|
-
);
|
|
249
|
+
return this._resolveBinding(fastBinding as Binding<Value>, undefined, resolutionPath, resolutionStack);
|
|
268
250
|
}
|
|
269
251
|
|
|
270
252
|
return this.resolve(token, undefined, resolutionPath, resolutionStack);
|
|
@@ -281,11 +263,7 @@ export class DependencyResolver {
|
|
|
281
263
|
if (found === undefined) {
|
|
282
264
|
const ownBindings = this._registry.getAll(token);
|
|
283
265
|
if (ownBindings.length > 0) {
|
|
284
|
-
throw new NoMatchingBindingError(
|
|
285
|
-
this._getTokenName(token),
|
|
286
|
-
hint ?? {},
|
|
287
|
-
this._getAvailableSlots(token),
|
|
288
|
-
);
|
|
266
|
+
throw new NoMatchingBindingError(this._getTokenName(token), hint ?? {}, this._getAvailableSlots(token));
|
|
289
267
|
}
|
|
290
268
|
throw new TokenNotBoundError(this._getTokenName(token));
|
|
291
269
|
}
|
|
@@ -294,24 +272,14 @@ export class DependencyResolver {
|
|
|
294
272
|
|
|
295
273
|
// Follow alias
|
|
296
274
|
if (binding.kind === "alias") {
|
|
297
|
-
return this.resolve(
|
|
298
|
-
binding.target as Token<Value> | Constructor<Value>,
|
|
299
|
-
hint,
|
|
300
|
-
resolutionPath,
|
|
301
|
-
resolutionStack,
|
|
302
|
-
);
|
|
275
|
+
return this.resolve(binding.target as Token<Value> | Constructor<Value>, hint, resolutionPath, resolutionStack);
|
|
303
276
|
}
|
|
304
277
|
|
|
305
278
|
const scope = (binding as BindingWithScope).scope ?? "transient";
|
|
306
279
|
|
|
307
280
|
// Singleton from a parent resolver: delegate so the parent caches it correctly
|
|
308
281
|
if (scope === "singleton" && owner !== this) {
|
|
309
|
-
return owner._resolveBinding(
|
|
310
|
-
binding as Binding<Value>,
|
|
311
|
-
hint,
|
|
312
|
-
resolutionPath,
|
|
313
|
-
resolutionStack,
|
|
314
|
-
);
|
|
282
|
+
return owner._resolveBinding(binding as Binding<Value>, hint, resolutionPath, resolutionStack);
|
|
315
283
|
}
|
|
316
284
|
|
|
317
285
|
// Scoped/transient (or own singleton): resolve with this resolver's container/scope
|
|
@@ -361,11 +329,7 @@ export class DependencyResolver {
|
|
|
361
329
|
}
|
|
362
330
|
|
|
363
331
|
// Circular dependency detection
|
|
364
|
-
if (
|
|
365
|
-
resolutionSet !== undefined
|
|
366
|
-
? resolutionSet.has(tokenDisplayName)
|
|
367
|
-
: resolutionPath.includes(tokenDisplayName)
|
|
368
|
-
) {
|
|
332
|
+
if (resolutionSet !== undefined ? resolutionSet.has(tokenDisplayName) : resolutionPath.includes(tokenDisplayName)) {
|
|
369
333
|
const cycle = [...resolutionPath, tokenDisplayName];
|
|
370
334
|
throw new CircularDependencyError(cycle);
|
|
371
335
|
}
|
|
@@ -375,11 +339,7 @@ export class DependencyResolver {
|
|
|
375
339
|
resolutionStack.push(frame);
|
|
376
340
|
const needsActivation = this._needsActivation(binding);
|
|
377
341
|
if (!needsActivation && scope === "transient" && binding.kind === "dynamic") {
|
|
378
|
-
const resolutionCtx = this._acquireSyncResolutionContext(
|
|
379
|
-
resolutionPath,
|
|
380
|
-
resolutionStack,
|
|
381
|
-
hint,
|
|
382
|
-
);
|
|
342
|
+
const resolutionCtx = this._acquireSyncResolutionContext(resolutionPath, resolutionStack, hint);
|
|
383
343
|
try {
|
|
384
344
|
const dynamicResult = binding.factory(resolutionCtx);
|
|
385
345
|
if (dynamicResult instanceof Promise) {
|
|
@@ -403,12 +363,7 @@ export class DependencyResolver {
|
|
|
403
363
|
? this._acquireSyncResolutionContext(resolutionPath, resolutionStack, hint)
|
|
404
364
|
: undefined;
|
|
405
365
|
|
|
406
|
-
const instance = this._instantiateSync(
|
|
407
|
-
binding,
|
|
408
|
-
resolutionCtx,
|
|
409
|
-
resolutionPath,
|
|
410
|
-
resolutionStack,
|
|
411
|
-
);
|
|
366
|
+
const instance = this._instantiateSync(binding, resolutionCtx, resolutionPath, resolutionStack);
|
|
412
367
|
|
|
413
368
|
const shouldActivate = this._refreshActivationCacheIfNeeded(binding, needsActivation);
|
|
414
369
|
const activated = shouldActivate
|
|
@@ -501,78 +456,32 @@ export class DependencyResolver {
|
|
|
501
456
|
const param = meta.params[0]!;
|
|
502
457
|
const paramHint = injectionSlotToResolveOptions(param);
|
|
503
458
|
if (param.multi) {
|
|
504
|
-
return [
|
|
505
|
-
this.resolveAll(
|
|
506
|
-
param.token as Token<unknown> | Constructor,
|
|
507
|
-
paramHint,
|
|
508
|
-
resolutionPath,
|
|
509
|
-
resolutionStack,
|
|
510
|
-
),
|
|
511
|
-
];
|
|
459
|
+
return [this.resolveAll(param.token, paramHint, resolutionPath, resolutionStack)];
|
|
512
460
|
}
|
|
513
461
|
if (param.optional) {
|
|
514
|
-
return [
|
|
515
|
-
this.resolveOptional(
|
|
516
|
-
param.token as Token<unknown> | Constructor,
|
|
517
|
-
paramHint,
|
|
518
|
-
resolutionPath,
|
|
519
|
-
resolutionStack,
|
|
520
|
-
),
|
|
521
|
-
];
|
|
462
|
+
return [this.resolveOptional(param.token, paramHint, resolutionPath, resolutionStack)];
|
|
522
463
|
}
|
|
523
464
|
if (paramHint === undefined) {
|
|
524
|
-
return [
|
|
525
|
-
this.resolveFromContext(
|
|
526
|
-
param.token as Token<unknown> | Constructor,
|
|
527
|
-
resolutionPath,
|
|
528
|
-
resolutionStack,
|
|
529
|
-
),
|
|
530
|
-
];
|
|
465
|
+
return [this.resolveFromContext(param.token, resolutionPath, resolutionStack)];
|
|
531
466
|
}
|
|
532
|
-
return [
|
|
533
|
-
this.resolve(
|
|
534
|
-
param.token as Token<unknown> | Constructor,
|
|
535
|
-
paramHint,
|
|
536
|
-
resolutionPath,
|
|
537
|
-
resolutionStack,
|
|
538
|
-
),
|
|
539
|
-
];
|
|
467
|
+
return [this.resolve(param.token, paramHint, resolutionPath, resolutionStack)];
|
|
540
468
|
}
|
|
541
469
|
const deps = new Array<unknown>(meta.params.length);
|
|
542
470
|
for (let index = 0; index < meta.params.length; index += 1) {
|
|
543
471
|
const param = meta.params[index]!;
|
|
544
472
|
const paramHint = injectionSlotToResolveOptions(param);
|
|
545
473
|
if (param.multi) {
|
|
546
|
-
deps[index] = this.resolveAll(
|
|
547
|
-
param.token as Token<unknown> | Constructor,
|
|
548
|
-
paramHint,
|
|
549
|
-
resolutionPath,
|
|
550
|
-
resolutionStack,
|
|
551
|
-
);
|
|
474
|
+
deps[index] = this.resolveAll(param.token, paramHint, resolutionPath, resolutionStack);
|
|
552
475
|
continue;
|
|
553
476
|
}
|
|
554
477
|
if (param.optional) {
|
|
555
|
-
deps[index] = this.resolveOptional(
|
|
556
|
-
param.token as Token<unknown> | Constructor,
|
|
557
|
-
paramHint,
|
|
558
|
-
resolutionPath,
|
|
559
|
-
resolutionStack,
|
|
560
|
-
);
|
|
478
|
+
deps[index] = this.resolveOptional(param.token, paramHint, resolutionPath, resolutionStack);
|
|
561
479
|
continue;
|
|
562
480
|
}
|
|
563
481
|
deps[index] =
|
|
564
482
|
paramHint === undefined
|
|
565
|
-
? this.resolveFromContext(
|
|
566
|
-
|
|
567
|
-
resolutionPath,
|
|
568
|
-
resolutionStack,
|
|
569
|
-
)
|
|
570
|
-
: this.resolve(
|
|
571
|
-
param.token as Token<unknown> | Constructor,
|
|
572
|
-
paramHint,
|
|
573
|
-
resolutionPath,
|
|
574
|
-
resolutionStack,
|
|
575
|
-
);
|
|
483
|
+
? this.resolveFromContext(param.token, resolutionPath, resolutionStack)
|
|
484
|
+
: this.resolve(param.token, paramHint, resolutionPath, resolutionStack);
|
|
576
485
|
}
|
|
577
486
|
return deps;
|
|
578
487
|
}
|
|
@@ -606,17 +515,8 @@ export class DependencyResolver {
|
|
|
606
515
|
}
|
|
607
516
|
resolved[index] =
|
|
608
517
|
depHint === undefined
|
|
609
|
-
? this.resolveFromContext(
|
|
610
|
-
|
|
611
|
-
resolutionPath,
|
|
612
|
-
resolutionStack,
|
|
613
|
-
)
|
|
614
|
-
: this.resolve(
|
|
615
|
-
dep.token as Token<unknown> | Constructor,
|
|
616
|
-
depHint,
|
|
617
|
-
resolutionPath,
|
|
618
|
-
resolutionStack,
|
|
619
|
-
);
|
|
518
|
+
? this.resolveFromContext(dep.token as Token<unknown> | Constructor, resolutionPath, resolutionStack)
|
|
519
|
+
: this.resolve(dep.token as Token<unknown> | Constructor, depHint, resolutionPath, resolutionStack);
|
|
620
520
|
}
|
|
621
521
|
return resolved;
|
|
622
522
|
}
|
|
@@ -697,8 +597,7 @@ export class DependencyResolver {
|
|
|
697
597
|
scope === "transient" &&
|
|
698
598
|
(fastBinding.kind === "dynamic" || fastBinding.kind === "dynamic-async") &&
|
|
699
599
|
fastBinding.onActivation === undefined &&
|
|
700
|
-
(this._lifecycle.activationVersion === 0 ||
|
|
701
|
-
!this._lifecycle.hasActivationHandlers(fastBinding.token))
|
|
600
|
+
(this._lifecycle.activationVersion === 0 || !this._lifecycle.hasActivationHandlers(fastBinding.token))
|
|
702
601
|
) {
|
|
703
602
|
return this._resolveTransientDynamicAsyncFromContext(
|
|
704
603
|
fastBinding as Binding<Value> & { kind: "dynamic" | "dynamic-async" },
|
|
@@ -711,20 +610,13 @@ export class DependencyResolver {
|
|
|
711
610
|
}
|
|
712
611
|
if (scope === "scoped") {
|
|
713
612
|
if (!this._scope.isChild) {
|
|
714
|
-
return Promise.reject(
|
|
715
|
-
new MissingScopeContextError(this._getTokenName(fastBinding.token)),
|
|
716
|
-
);
|
|
613
|
+
return Promise.reject(new MissingScopeContextError(this._getTokenName(fastBinding.token)));
|
|
717
614
|
}
|
|
718
615
|
if (this._scope.hasScoped(fastBinding.id)) {
|
|
719
616
|
return Promise.resolve(this._scope.getScoped<Value>(fastBinding.id));
|
|
720
617
|
}
|
|
721
618
|
}
|
|
722
|
-
return this._resolveBindingAsync(
|
|
723
|
-
fastBinding as Binding<Value>,
|
|
724
|
-
undefined,
|
|
725
|
-
resolutionPath,
|
|
726
|
-
resolutionStack,
|
|
727
|
-
);
|
|
619
|
+
return this._resolveBindingAsync(fastBinding as Binding<Value>, undefined, resolutionPath, resolutionStack);
|
|
728
620
|
}
|
|
729
621
|
|
|
730
622
|
return this.resolveAsync(token, undefined, resolutionPath, resolutionStack);
|
|
@@ -741,11 +633,7 @@ export class DependencyResolver {
|
|
|
741
633
|
if (found === undefined) {
|
|
742
634
|
const ownBindings = this._registry.getAll(token);
|
|
743
635
|
if (ownBindings.length > 0) {
|
|
744
|
-
throw new NoMatchingBindingError(
|
|
745
|
-
this._getTokenName(token),
|
|
746
|
-
hint ?? {},
|
|
747
|
-
this._getAvailableSlots(token),
|
|
748
|
-
);
|
|
636
|
+
throw new NoMatchingBindingError(this._getTokenName(token), hint ?? {}, this._getAvailableSlots(token));
|
|
749
637
|
}
|
|
750
638
|
throw new TokenNotBoundError(this._getTokenName(token));
|
|
751
639
|
}
|
|
@@ -764,20 +652,10 @@ export class DependencyResolver {
|
|
|
764
652
|
const scope = (binding as BindingWithScope).scope ?? "transient";
|
|
765
653
|
|
|
766
654
|
if (scope === "singleton" && owner !== this) {
|
|
767
|
-
return owner._resolveBindingAsync(
|
|
768
|
-
binding as Binding<Value>,
|
|
769
|
-
hint,
|
|
770
|
-
resolutionPath,
|
|
771
|
-
resolutionStack,
|
|
772
|
-
);
|
|
655
|
+
return owner._resolveBindingAsync(binding as Binding<Value>, hint, resolutionPath, resolutionStack);
|
|
773
656
|
}
|
|
774
657
|
|
|
775
|
-
return this._resolveBindingAsync(
|
|
776
|
-
binding as Binding<Value>,
|
|
777
|
-
hint,
|
|
778
|
-
resolutionPath,
|
|
779
|
-
resolutionStack,
|
|
780
|
-
);
|
|
658
|
+
return this._resolveBindingAsync(binding as Binding<Value>, hint, resolutionPath, resolutionStack);
|
|
781
659
|
}
|
|
782
660
|
|
|
783
661
|
private async _resolveBindingAsync<const Value>(
|
|
@@ -827,11 +705,7 @@ export class DependencyResolver {
|
|
|
827
705
|
pathWithSet[RESOLUTION_SET_KEY] = resolutionSet;
|
|
828
706
|
}
|
|
829
707
|
|
|
830
|
-
if (
|
|
831
|
-
resolutionSet !== undefined
|
|
832
|
-
? resolutionSet.has(frameName)
|
|
833
|
-
: resolutionPath.includes(frameName)
|
|
834
|
-
) {
|
|
708
|
+
if (resolutionSet !== undefined ? resolutionSet.has(frameName) : resolutionPath.includes(frameName)) {
|
|
835
709
|
throw new CircularDependencyError([...resolutionPath, frameName]);
|
|
836
710
|
}
|
|
837
711
|
|
|
@@ -839,11 +713,7 @@ export class DependencyResolver {
|
|
|
839
713
|
resolutionSet?.add(frameName);
|
|
840
714
|
resolutionStack.push(frame);
|
|
841
715
|
const needsActivation = this._needsActivation(binding);
|
|
842
|
-
if (
|
|
843
|
-
!needsActivation &&
|
|
844
|
-
scope === "transient" &&
|
|
845
|
-
(binding.kind === "dynamic" || binding.kind === "dynamic-async")
|
|
846
|
-
) {
|
|
716
|
+
if (!needsActivation && scope === "transient" && (binding.kind === "dynamic" || binding.kind === "dynamic-async")) {
|
|
847
717
|
const resolutionCtx = new DefaultResolutionContext(
|
|
848
718
|
this as unknown as ResolverCallbacks,
|
|
849
719
|
resolutionPath,
|
|
@@ -865,23 +735,13 @@ export class DependencyResolver {
|
|
|
865
735
|
|
|
866
736
|
const needsResolutionContext = needsActivation || this._requiresResolutionContext(binding);
|
|
867
737
|
const resolutionCtx = needsResolutionContext
|
|
868
|
-
? new DefaultResolutionContext(
|
|
869
|
-
this as unknown as ResolverCallbacks,
|
|
870
|
-
resolutionPath,
|
|
871
|
-
resolutionStack,
|
|
872
|
-
hint,
|
|
873
|
-
)
|
|
738
|
+
? new DefaultResolutionContext(this as unknown as ResolverCallbacks, resolutionPath, resolutionStack, hint)
|
|
874
739
|
: undefined;
|
|
875
740
|
|
|
876
741
|
try {
|
|
877
742
|
if (scope === "singleton") {
|
|
878
743
|
const createSingletonPromise = async (): Promise<Value> => {
|
|
879
|
-
const instance = await this._instantiateAsync(
|
|
880
|
-
binding,
|
|
881
|
-
resolutionCtx,
|
|
882
|
-
resolutionPath,
|
|
883
|
-
resolutionStack,
|
|
884
|
-
);
|
|
744
|
+
const instance = await this._instantiateAsync(binding, resolutionCtx, resolutionPath, resolutionStack);
|
|
885
745
|
|
|
886
746
|
const shouldActivate = this._refreshActivationCacheIfNeeded(binding, needsActivation);
|
|
887
747
|
const activated = shouldActivate
|
|
@@ -906,12 +766,7 @@ export class DependencyResolver {
|
|
|
906
766
|
return await singletonPromise;
|
|
907
767
|
}
|
|
908
768
|
|
|
909
|
-
const instance = await this._instantiateAsync(
|
|
910
|
-
binding,
|
|
911
|
-
resolutionCtx,
|
|
912
|
-
resolutionPath,
|
|
913
|
-
resolutionStack,
|
|
914
|
-
);
|
|
769
|
+
const instance = await this._instantiateAsync(binding, resolutionCtx, resolutionPath, resolutionStack);
|
|
915
770
|
|
|
916
771
|
const shouldActivate = this._refreshActivationCacheIfNeeded(binding, needsActivation);
|
|
917
772
|
const activated = shouldActivate
|
|
@@ -960,11 +815,7 @@ export class DependencyResolver {
|
|
|
960
815
|
return binding.factory(ctx);
|
|
961
816
|
|
|
962
817
|
case "class": {
|
|
963
|
-
const deps = await this._resolveClassDepsAsync(
|
|
964
|
-
binding.target,
|
|
965
|
-
resolutionPath,
|
|
966
|
-
resolutionStack,
|
|
967
|
-
);
|
|
818
|
+
const deps = await this._resolveClassDepsAsync(binding.target, resolutionPath, resolutionStack);
|
|
968
819
|
const instance = this._instantiateClass(binding.target, deps);
|
|
969
820
|
return instance as Value;
|
|
970
821
|
}
|
|
@@ -973,21 +824,13 @@ export class DependencyResolver {
|
|
|
973
824
|
if (ctx === undefined) {
|
|
974
825
|
throw new InternalError("resolved binding requires resolution context");
|
|
975
826
|
}
|
|
976
|
-
const deps = await this._resolveDescriptorDepsAsync(
|
|
977
|
-
binding.deps,
|
|
978
|
-
resolutionPath,
|
|
979
|
-
resolutionStack,
|
|
980
|
-
);
|
|
827
|
+
const deps = await this._resolveDescriptorDepsAsync(binding.deps, resolutionPath, resolutionStack);
|
|
981
828
|
const factoryResult = binding.factory(...deps);
|
|
982
829
|
return factoryResult instanceof Promise ? factoryResult : Promise.resolve(factoryResult);
|
|
983
830
|
}
|
|
984
831
|
|
|
985
832
|
case "resolved-async": {
|
|
986
|
-
const deps = await this._resolveDescriptorDepsAsync(
|
|
987
|
-
binding.deps,
|
|
988
|
-
resolutionPath,
|
|
989
|
-
resolutionStack,
|
|
990
|
-
);
|
|
833
|
+
const deps = await this._resolveDescriptorDepsAsync(binding.deps, resolutionPath, resolutionStack);
|
|
991
834
|
return binding.factory(...deps);
|
|
992
835
|
}
|
|
993
836
|
|
|
@@ -1015,42 +858,15 @@ export class DependencyResolver {
|
|
|
1015
858
|
const param = meta.params[0]!;
|
|
1016
859
|
const paramHint = injectionSlotToResolveOptions(param);
|
|
1017
860
|
if (param.multi) {
|
|
1018
|
-
return [
|
|
1019
|
-
await this.resolveAllAsync(
|
|
1020
|
-
param.token as Token<unknown> | Constructor,
|
|
1021
|
-
paramHint,
|
|
1022
|
-
resolutionPath,
|
|
1023
|
-
resolutionStack,
|
|
1024
|
-
),
|
|
1025
|
-
];
|
|
861
|
+
return [await this.resolveAllAsync(param.token, paramHint, resolutionPath, resolutionStack)];
|
|
1026
862
|
}
|
|
1027
863
|
if (param.optional) {
|
|
1028
|
-
return [
|
|
1029
|
-
await this.resolveOptionalAsync(
|
|
1030
|
-
param.token as Token<unknown> | Constructor,
|
|
1031
|
-
paramHint,
|
|
1032
|
-
resolutionPath,
|
|
1033
|
-
resolutionStack,
|
|
1034
|
-
),
|
|
1035
|
-
];
|
|
864
|
+
return [await this.resolveOptionalAsync(param.token, paramHint, resolutionPath, resolutionStack)];
|
|
1036
865
|
}
|
|
1037
866
|
if (paramHint === undefined) {
|
|
1038
|
-
return [
|
|
1039
|
-
await this.resolveAsyncFromContext(
|
|
1040
|
-
param.token as Token<unknown> | Constructor,
|
|
1041
|
-
resolutionPath,
|
|
1042
|
-
resolutionStack,
|
|
1043
|
-
),
|
|
1044
|
-
];
|
|
867
|
+
return [await this.resolveAsyncFromContext(param.token, resolutionPath, resolutionStack)];
|
|
1045
868
|
}
|
|
1046
|
-
return [
|
|
1047
|
-
await this.resolveAsync(
|
|
1048
|
-
param.token as Token<unknown> | Constructor,
|
|
1049
|
-
paramHint,
|
|
1050
|
-
resolutionPath,
|
|
1051
|
-
resolutionStack,
|
|
1052
|
-
),
|
|
1053
|
-
];
|
|
869
|
+
return [await this.resolveAsync(param.token, paramHint, resolutionPath, resolutionStack)];
|
|
1054
870
|
}
|
|
1055
871
|
const pending = new Array<Promise<unknown>>(meta.params.length);
|
|
1056
872
|
const shouldCloneContext = meta.params.length > 1;
|
|
@@ -1059,14 +875,14 @@ export class DependencyResolver {
|
|
|
1059
875
|
const paramHint = injectionSlotToResolveOptions(param);
|
|
1060
876
|
if (param.multi) {
|
|
1061
877
|
pending[index] = this.resolveAllAsync(
|
|
1062
|
-
param.token
|
|
878
|
+
param.token,
|
|
1063
879
|
paramHint,
|
|
1064
880
|
shouldCloneContext ? [...resolutionPath] : resolutionPath,
|
|
1065
881
|
shouldCloneContext ? [...resolutionStack] : resolutionStack,
|
|
1066
882
|
);
|
|
1067
883
|
} else if (param.optional) {
|
|
1068
884
|
pending[index] = this.resolveOptionalAsync(
|
|
1069
|
-
param.token
|
|
885
|
+
param.token,
|
|
1070
886
|
paramHint,
|
|
1071
887
|
shouldCloneContext ? [...resolutionPath] : resolutionPath,
|
|
1072
888
|
shouldCloneContext ? [...resolutionStack] : resolutionStack,
|
|
@@ -1075,12 +891,12 @@ export class DependencyResolver {
|
|
|
1075
891
|
pending[index] =
|
|
1076
892
|
paramHint === undefined
|
|
1077
893
|
? this.resolveAsyncFromContext(
|
|
1078
|
-
param.token
|
|
894
|
+
param.token,
|
|
1079
895
|
shouldCloneContext ? [...resolutionPath] : resolutionPath,
|
|
1080
896
|
shouldCloneContext ? [...resolutionStack] : resolutionStack,
|
|
1081
897
|
)
|
|
1082
898
|
: this.resolveAsync(
|
|
1083
|
-
param.token
|
|
899
|
+
param.token,
|
|
1084
900
|
paramHint,
|
|
1085
901
|
shouldCloneContext ? [...resolutionPath] : resolutionPath,
|
|
1086
902
|
shouldCloneContext ? [...resolutionStack] : resolutionStack,
|
|
@@ -1207,10 +1023,7 @@ export class DependencyResolver {
|
|
|
1207
1023
|
return result;
|
|
1208
1024
|
}
|
|
1209
1025
|
|
|
1210
|
-
private _getSimpleNamedBindingsFromChain(
|
|
1211
|
-
token: Token<unknown> | Constructor,
|
|
1212
|
-
name: string,
|
|
1213
|
-
): Array<Binding> {
|
|
1026
|
+
private _getSimpleNamedBindingsFromChain(token: Token<unknown> | Constructor, name: string): Array<Binding> {
|
|
1214
1027
|
const ownBinding = this._registry.getSimpleNamed(token, name);
|
|
1215
1028
|
if (this._parent === undefined) {
|
|
1216
1029
|
return ownBinding !== undefined ? [ownBinding] : [];
|
|
@@ -1333,11 +1146,7 @@ export class DependencyResolver {
|
|
|
1333
1146
|
hintTags: ReadonlyArray<BindingTag> | undefined,
|
|
1334
1147
|
singleHintTag: BindingTag | undefined,
|
|
1335
1148
|
): boolean {
|
|
1336
|
-
if (
|
|
1337
|
-
singleHintTag !== undefined &&
|
|
1338
|
-
singleHintTag[0] === tagKey &&
|
|
1339
|
-
Object.is(singleHintTag[1], tagValue)
|
|
1340
|
-
) {
|
|
1149
|
+
if (singleHintTag !== undefined && singleHintTag[0] === tagKey && Object.is(singleHintTag[1], tagValue)) {
|
|
1341
1150
|
return true;
|
|
1342
1151
|
}
|
|
1343
1152
|
if (hintTags === undefined || hintTags.length === 0) {
|
|
@@ -1369,11 +1178,7 @@ export class DependencyResolver {
|
|
|
1369
1178
|
}
|
|
1370
1179
|
resolutionPath.push(tokenDisplayName);
|
|
1371
1180
|
resolutionStack.push(frame);
|
|
1372
|
-
const resolutionCtx = this._acquireSyncResolutionContext(
|
|
1373
|
-
resolutionPath,
|
|
1374
|
-
resolutionStack,
|
|
1375
|
-
undefined,
|
|
1376
|
-
);
|
|
1181
|
+
const resolutionCtx = this._acquireSyncResolutionContext(resolutionPath, resolutionStack, undefined);
|
|
1377
1182
|
try {
|
|
1378
1183
|
const dynamicResult = binding.factory(resolutionCtx);
|
|
1379
1184
|
if (dynamicResult instanceof Promise) {
|
|
@@ -1477,11 +1282,7 @@ export class DependencyResolver {
|
|
|
1477
1282
|
resolutionPath.push(tokenDisplayName);
|
|
1478
1283
|
resolutionSet.add(tokenDisplayName);
|
|
1479
1284
|
resolutionStack.push(frame);
|
|
1480
|
-
const resolutionCtx = this._acquireSyncResolutionContext(
|
|
1481
|
-
resolutionPath,
|
|
1482
|
-
resolutionStack,
|
|
1483
|
-
undefined,
|
|
1484
|
-
);
|
|
1285
|
+
const resolutionCtx = this._acquireSyncResolutionContext(resolutionPath, resolutionStack, undefined);
|
|
1485
1286
|
try {
|
|
1486
1287
|
const dynamicResult = binding.factory(resolutionCtx);
|
|
1487
1288
|
if (dynamicResult instanceof Promise) {
|
|
@@ -1538,12 +1339,7 @@ export class DependencyResolver {
|
|
|
1538
1339
|
);
|
|
1539
1340
|
this._deepAsyncCtx = ctx;
|
|
1540
1341
|
} else {
|
|
1541
|
-
existing.reset(
|
|
1542
|
-
this as unknown as ResolverCallbacks,
|
|
1543
|
-
resolutionPath,
|
|
1544
|
-
resolutionStack,
|
|
1545
|
-
undefined,
|
|
1546
|
-
);
|
|
1342
|
+
existing.reset(this as unknown as ResolverCallbacks, resolutionPath, resolutionStack, undefined);
|
|
1547
1343
|
ctx = existing;
|
|
1548
1344
|
}
|
|
1549
1345
|
this._deepAsyncCtxPath = resolutionPath;
|
|
@@ -1572,9 +1368,7 @@ export class DependencyResolver {
|
|
|
1572
1368
|
} else {
|
|
1573
1369
|
const factoryResult = binding.factory(ctx);
|
|
1574
1370
|
factoryPromise =
|
|
1575
|
-
factoryResult instanceof Promise
|
|
1576
|
-
? (factoryResult as Promise<Value>)
|
|
1577
|
-
: Promise.resolve(factoryResult);
|
|
1371
|
+
factoryResult instanceof Promise ? (factoryResult as Promise<Value>) : Promise.resolve(factoryResult);
|
|
1578
1372
|
}
|
|
1579
1373
|
} catch (err) {
|
|
1580
1374
|
// Synchronous throw from the factory (rare) — clean up immediately.
|
|
@@ -1663,12 +1457,7 @@ export class DependencyResolver {
|
|
|
1663
1457
|
return binding.value;
|
|
1664
1458
|
}
|
|
1665
1459
|
if (binding.kind === "alias") {
|
|
1666
|
-
return this.resolve(
|
|
1667
|
-
binding.target as Token<Value> | Constructor<Value>,
|
|
1668
|
-
hint,
|
|
1669
|
-
resolutionPath,
|
|
1670
|
-
resolutionStack,
|
|
1671
|
-
);
|
|
1460
|
+
return this.resolve(binding.target, hint, resolutionPath, resolutionStack);
|
|
1672
1461
|
}
|
|
1673
1462
|
const scope = (binding as BindingWithScope).scope ?? "transient";
|
|
1674
1463
|
if (scope === "singleton" && this._scope.hasSingleton(binding.id)) {
|
|
@@ -1701,12 +1490,7 @@ export class DependencyResolver {
|
|
|
1701
1490
|
const isolatedPath = [...resolutionPath];
|
|
1702
1491
|
const isolatedStack = [...resolutionStack];
|
|
1703
1492
|
if (binding.kind === "alias") {
|
|
1704
|
-
return this.resolveAsync(
|
|
1705
|
-
binding.target as Token<Value> | Constructor<Value>,
|
|
1706
|
-
hint,
|
|
1707
|
-
isolatedPath,
|
|
1708
|
-
isolatedStack,
|
|
1709
|
-
);
|
|
1493
|
+
return this.resolveAsync(binding.target, hint, isolatedPath, isolatedStack);
|
|
1710
1494
|
}
|
|
1711
1495
|
const scope = (binding as BindingWithScope).scope ?? "transient";
|
|
1712
1496
|
if (scope === "singleton" && this._scope.hasSingleton(binding.id)) {
|
|
@@ -1729,13 +1513,7 @@ export class DependencyResolver {
|
|
|
1729
1513
|
return existing;
|
|
1730
1514
|
}
|
|
1731
1515
|
const scope = (binding as BindingWithScope).scope ?? "transient";
|
|
1732
|
-
const frame = buildResolutionFrame(
|
|
1733
|
-
tokenName(binding.token),
|
|
1734
|
-
scope,
|
|
1735
|
-
binding.id,
|
|
1736
|
-
binding.kind,
|
|
1737
|
-
binding.slot,
|
|
1738
|
-
);
|
|
1516
|
+
const frame = buildResolutionFrame(tokenName(binding.token), scope, binding.id, binding.kind, binding.slot);
|
|
1739
1517
|
this._frameByBindingId.set(binding.id, frame);
|
|
1740
1518
|
return frame;
|
|
1741
1519
|
}
|
|
@@ -1761,8 +1539,7 @@ export class DependencyResolver {
|
|
|
1761
1539
|
}
|
|
1762
1540
|
|
|
1763
1541
|
if (binding.kind === "class") {
|
|
1764
|
-
let hasActivation =
|
|
1765
|
-
this._lifecycle.hasActivationHandlers(binding.token) || binding.onActivation !== undefined;
|
|
1542
|
+
let hasActivation = this._lifecycle.hasActivationHandlers(binding.token) || binding.onActivation !== undefined;
|
|
1766
1543
|
const cachedPostConstruct = this._classHasPostConstruct.get(binding.target);
|
|
1767
1544
|
// Unknown class lifecycle metadata: activate once, then cache after first instantiation.
|
|
1768
1545
|
if (cachedPostConstruct === undefined) {
|
|
@@ -1788,9 +1565,7 @@ export class DependencyResolver {
|
|
|
1788
1565
|
private _refreshClassPostConstructCache(target: Constructor): void {
|
|
1789
1566
|
const lifecycle = this._metadataReader.getLifecycleMetadata(target);
|
|
1790
1567
|
const hasPostConstruct =
|
|
1791
|
-
lifecycle !== undefined &&
|
|
1792
|
-
lifecycle.postConstruct !== undefined &&
|
|
1793
|
-
lifecycle.postConstruct.length > 0;
|
|
1568
|
+
lifecycle !== undefined && lifecycle.postConstruct !== undefined && lifecycle.postConstruct.length > 0;
|
|
1794
1569
|
this._classHasPostConstruct.set(target, hasPostConstruct);
|
|
1795
1570
|
}
|
|
1796
1571
|
|
|
@@ -1798,10 +1573,7 @@ export class DependencyResolver {
|
|
|
1798
1573
|
* Refreshes the post-construct cache for class bindings on first instantiation and
|
|
1799
1574
|
* returns the (possibly updated) shouldActivate flag.
|
|
1800
1575
|
*/
|
|
1801
|
-
private _refreshActivationCacheIfNeeded<Value>(
|
|
1802
|
-
binding: Binding<Value>,
|
|
1803
|
-
needsActivation: boolean,
|
|
1804
|
-
): boolean {
|
|
1576
|
+
private _refreshActivationCacheIfNeeded<Value>(binding: Binding<Value>, needsActivation: boolean): boolean {
|
|
1805
1577
|
if (binding.kind === "class" && this._classHasPostConstruct.get(binding.target) === undefined) {
|
|
1806
1578
|
this._refreshClassPostConstructCache(binding.target);
|
|
1807
1579
|
this._activationNeedByBindingId.delete(binding.id);
|