@codefast/di 0.5.0-canary.2 → 0.5.0-canary.4
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 +8 -0
- package/README.md +3 -3
- package/dist/binding-select.d.mts +3 -3
- package/dist/binding-select.mjs +32 -32
- package/dist/container.d.mts +8 -8
- package/dist/container.mjs +32 -32
- package/dist/decorators/inject.mjs +2 -2
- package/dist/environment.d.mts +15 -15
- package/dist/environment.mjs +23 -23
- package/dist/errors.d.mts +2 -2
- package/dist/errors.mjs +5 -5
- package/dist/inspector.d.mts +3 -3
- package/dist/inspector.mjs +7 -7
- package/dist/resolve-options.d.mts +1 -1
- package/dist/resolve-options.mjs +1 -1
- package/dist/resolver.d.mts +9 -9
- package/dist/resolver.mjs +110 -110
- package/dist/types.d.mts +8 -8
- package/package.json +4 -4
- package/src/binding-select.ts +46 -39
- package/src/container.ts +48 -42
- package/src/decorators/inject.ts +4 -2
- package/src/environment.ts +32 -29
- package/src/errors.ts +5 -5
- package/src/inspector.ts +8 -8
- package/src/resolve-options.ts +1 -1
- package/src/resolver.ts +138 -121
- package/src/types.ts +11 -8
package/src/resolver.ts
CHANGED
|
@@ -42,7 +42,7 @@ const ROOT_CONSTRAINT_CONTEXT = {
|
|
|
42
42
|
resolutionStack: EMPTY_FRAME_LIST,
|
|
43
43
|
parent: undefined,
|
|
44
44
|
ancestors: EMPTY_FRAME_LIST,
|
|
45
|
-
|
|
45
|
+
currentResolveOptions: undefined,
|
|
46
46
|
};
|
|
47
47
|
|
|
48
48
|
/**
|
|
@@ -128,26 +128,34 @@ export class DependencyResolver {
|
|
|
128
128
|
|
|
129
129
|
private _findBinding(
|
|
130
130
|
token: Token<unknown> | Constructor,
|
|
131
|
-
|
|
131
|
+
options: ResolveOptions | undefined,
|
|
132
132
|
resolutionPath: Array<string>,
|
|
133
133
|
resolutionStack: Array<ResolutionFrame>,
|
|
134
134
|
): { binding: Binding; owner: DependencyResolver } | undefined {
|
|
135
|
-
if (
|
|
135
|
+
if (options === undefined) {
|
|
136
136
|
const fastDefaultBinding = this._registry.getFastDefault(token);
|
|
137
137
|
if (fastDefaultBinding !== undefined) {
|
|
138
138
|
return { binding: fastDefaultBinding, owner: this };
|
|
139
139
|
}
|
|
140
140
|
}
|
|
141
141
|
|
|
142
|
-
if (
|
|
143
|
-
const namedBinding = this._registry.getSimpleNamed(token,
|
|
144
|
-
if (
|
|
142
|
+
if (options?.name !== undefined && options.tag === undefined && (options.tags?.length ?? 0) === 0) {
|
|
143
|
+
const namedBinding = this._registry.getSimpleNamed(token, options.name);
|
|
144
|
+
if (
|
|
145
|
+
namedBinding !== undefined &&
|
|
146
|
+
this._matchesBindingFast(namedBinding, options, resolutionPath, resolutionStack)
|
|
147
|
+
) {
|
|
145
148
|
return { binding: namedBinding, owner: this };
|
|
146
149
|
}
|
|
147
150
|
}
|
|
148
151
|
|
|
149
|
-
if (
|
|
150
|
-
|
|
152
|
+
if (
|
|
153
|
+
options !== undefined &&
|
|
154
|
+
options.name === undefined &&
|
|
155
|
+
options.tag === undefined &&
|
|
156
|
+
(options.tags?.length ?? 0) === 1
|
|
157
|
+
) {
|
|
158
|
+
const [tagKey, tagValue] = options.tags![0]!;
|
|
151
159
|
const tagged = this._registry.getSimpleTagged(token, tagKey, tagValue);
|
|
152
160
|
if (tagged !== undefined) {
|
|
153
161
|
return { binding: tagged, owner: this };
|
|
@@ -159,21 +167,21 @@ export class DependencyResolver {
|
|
|
159
167
|
if (bindings.length === 1) {
|
|
160
168
|
const onlyBinding = bindings[0]!;
|
|
161
169
|
const isDefaultSlot = onlyBinding.slot.name === undefined && onlyBinding.slot.tags.length === 0;
|
|
162
|
-
if (
|
|
170
|
+
if (options === undefined && isDefaultSlot && onlyBinding.predicate === undefined) {
|
|
163
171
|
return { binding: onlyBinding, owner: this };
|
|
164
172
|
}
|
|
165
|
-
if (this._matchesBindingFast(onlyBinding,
|
|
173
|
+
if (this._matchesBindingFast(onlyBinding, options, resolutionPath, resolutionStack)) {
|
|
166
174
|
return { binding: onlyBinding, owner: this };
|
|
167
175
|
}
|
|
168
176
|
}
|
|
169
|
-
const ctx = this._makeConstraintContext(resolutionPath, resolutionStack,
|
|
170
|
-
const binding = selectBinding(bindings,
|
|
177
|
+
const ctx = this._makeConstraintContext(resolutionPath, resolutionStack, options);
|
|
178
|
+
const binding = selectBinding(bindings, options, ctx, this._getTokenName(token));
|
|
171
179
|
if (binding !== undefined) {
|
|
172
180
|
return { binding, owner: this };
|
|
173
181
|
}
|
|
174
182
|
}
|
|
175
183
|
if (this._parent !== undefined) {
|
|
176
|
-
return this._parent._findBinding(token,
|
|
184
|
+
return this._parent._findBinding(token, options, resolutionPath, resolutionStack);
|
|
177
185
|
}
|
|
178
186
|
return undefined;
|
|
179
187
|
}
|
|
@@ -183,9 +191,9 @@ export class DependencyResolver {
|
|
|
183
191
|
*/
|
|
184
192
|
peekBindingForValidate(
|
|
185
193
|
token: Token<unknown> | Constructor,
|
|
186
|
-
|
|
194
|
+
options: ResolveOptions | undefined,
|
|
187
195
|
): { binding: Binding; owner: DependencyResolver } | undefined {
|
|
188
|
-
return this._findBinding(token,
|
|
196
|
+
return this._findBinding(token, options, [], []);
|
|
189
197
|
}
|
|
190
198
|
|
|
191
199
|
/**
|
|
@@ -193,17 +201,17 @@ export class DependencyResolver {
|
|
|
193
201
|
*/
|
|
194
202
|
peekCandidateBindingsForValidate(
|
|
195
203
|
token: Token<unknown> | Constructor,
|
|
196
|
-
|
|
204
|
+
options: ResolveOptions | undefined,
|
|
197
205
|
): Array<Binding> {
|
|
198
|
-
if (
|
|
199
|
-
return this._getSimpleNamedBindingsFromChain(token,
|
|
206
|
+
if (options?.name !== undefined && options.tag === undefined && (options.tags?.length ?? 0) === 0) {
|
|
207
|
+
return this._getSimpleNamedBindingsFromChain(token, options.name);
|
|
200
208
|
}
|
|
201
209
|
const allBindings = this._getAllBindingsFromChain(token);
|
|
202
210
|
if (allBindings.length === 0) {
|
|
203
211
|
return [];
|
|
204
212
|
}
|
|
205
|
-
const ctx = this._makeConstraintContext([], [],
|
|
206
|
-
return selectAllBindings(allBindings,
|
|
213
|
+
const ctx = this._makeConstraintContext([], [], options);
|
|
214
|
+
return selectAllBindings(allBindings, options, ctx);
|
|
207
215
|
}
|
|
208
216
|
|
|
209
217
|
// ── Sync resolve ───────────────────────────────────────────────────────────
|
|
@@ -254,16 +262,16 @@ export class DependencyResolver {
|
|
|
254
262
|
|
|
255
263
|
resolve<const Value>(
|
|
256
264
|
token: Token<Value> | Constructor<Value>,
|
|
257
|
-
|
|
265
|
+
options: ResolveOptions | undefined,
|
|
258
266
|
resolutionPath: Array<string>,
|
|
259
267
|
resolutionStack: Array<ResolutionFrame>,
|
|
260
268
|
): Value {
|
|
261
|
-
const found = this._findBinding(token,
|
|
269
|
+
const found = this._findBinding(token, options, resolutionPath, resolutionStack);
|
|
262
270
|
|
|
263
271
|
if (found === undefined) {
|
|
264
272
|
const ownBindings = this._registry.getAll(token);
|
|
265
273
|
if (ownBindings.length > 0) {
|
|
266
|
-
throw new NoMatchingBindingError(this._getTokenName(token),
|
|
274
|
+
throw new NoMatchingBindingError(this._getTokenName(token), options ?? {}, this._getAvailableSlots(token));
|
|
267
275
|
}
|
|
268
276
|
throw new TokenNotBoundError(this._getTokenName(token));
|
|
269
277
|
}
|
|
@@ -272,23 +280,28 @@ export class DependencyResolver {
|
|
|
272
280
|
|
|
273
281
|
// Follow alias
|
|
274
282
|
if (binding.kind === "alias") {
|
|
275
|
-
return this.resolve(
|
|
283
|
+
return this.resolve(
|
|
284
|
+
binding.target as Token<Value> | Constructor<Value>,
|
|
285
|
+
options,
|
|
286
|
+
resolutionPath,
|
|
287
|
+
resolutionStack,
|
|
288
|
+
);
|
|
276
289
|
}
|
|
277
290
|
|
|
278
291
|
const scope = (binding as BindingWithScope).scope ?? "transient";
|
|
279
292
|
|
|
280
293
|
// Singleton from a parent resolver: delegate so the parent caches it correctly
|
|
281
294
|
if (scope === "singleton" && owner !== this) {
|
|
282
|
-
return owner._resolveBinding(binding as Binding<Value>,
|
|
295
|
+
return owner._resolveBinding(binding as Binding<Value>, options, resolutionPath, resolutionStack);
|
|
283
296
|
}
|
|
284
297
|
|
|
285
298
|
// Scoped/transient (or own singleton): resolve with this resolver's container/scope
|
|
286
|
-
return this._resolveBinding(binding as Binding<Value>,
|
|
299
|
+
return this._resolveBinding(binding as Binding<Value>, options, resolutionPath, resolutionStack);
|
|
287
300
|
}
|
|
288
301
|
|
|
289
302
|
private _resolveBinding<const Value>(
|
|
290
303
|
binding: Binding<Value>,
|
|
291
|
-
|
|
304
|
+
options: ResolveOptions | undefined,
|
|
292
305
|
resolutionPath: Array<string>,
|
|
293
306
|
resolutionStack: Array<ResolutionFrame>,
|
|
294
307
|
): Value {
|
|
@@ -339,7 +352,7 @@ export class DependencyResolver {
|
|
|
339
352
|
resolutionStack.push(frame);
|
|
340
353
|
const needsActivation = this._needsActivation(binding);
|
|
341
354
|
if (!needsActivation && scope === "transient" && binding.kind === "dynamic") {
|
|
342
|
-
const resolutionCtx = this._acquireSyncResolutionContext(resolutionPath, resolutionStack,
|
|
355
|
+
const resolutionCtx = this._acquireSyncResolutionContext(resolutionPath, resolutionStack, options);
|
|
343
356
|
try {
|
|
344
357
|
const dynamicResult = binding.factory(resolutionCtx);
|
|
345
358
|
if (dynamicResult instanceof Promise) {
|
|
@@ -360,7 +373,7 @@ export class DependencyResolver {
|
|
|
360
373
|
try {
|
|
361
374
|
const needsResolutionContext = needsActivation || this._requiresResolutionContext(binding);
|
|
362
375
|
const resolutionCtx = needsResolutionContext
|
|
363
|
-
? this._acquireSyncResolutionContext(resolutionPath, resolutionStack,
|
|
376
|
+
? this._acquireSyncResolutionContext(resolutionPath, resolutionStack, options)
|
|
364
377
|
: undefined;
|
|
365
378
|
|
|
366
379
|
const instance = this._instantiateSync(binding, resolutionCtx, resolutionPath, resolutionStack);
|
|
@@ -454,34 +467,34 @@ export class DependencyResolver {
|
|
|
454
467
|
}
|
|
455
468
|
if (meta.params.length === 1) {
|
|
456
469
|
const param = meta.params[0]!;
|
|
457
|
-
const
|
|
470
|
+
const paramOptions = injectionSlotToResolveOptions(param);
|
|
458
471
|
if (param.multi) {
|
|
459
|
-
return [this.resolveAll(param.token,
|
|
472
|
+
return [this.resolveAll(param.token, paramOptions, resolutionPath, resolutionStack)];
|
|
460
473
|
}
|
|
461
474
|
if (param.optional) {
|
|
462
|
-
return [this.resolveOptional(param.token,
|
|
475
|
+
return [this.resolveOptional(param.token, paramOptions, resolutionPath, resolutionStack)];
|
|
463
476
|
}
|
|
464
|
-
if (
|
|
477
|
+
if (paramOptions === undefined) {
|
|
465
478
|
return [this.resolveFromContext(param.token, resolutionPath, resolutionStack)];
|
|
466
479
|
}
|
|
467
|
-
return [this.resolve(param.token,
|
|
480
|
+
return [this.resolve(param.token, paramOptions, resolutionPath, resolutionStack)];
|
|
468
481
|
}
|
|
469
482
|
const deps = new Array<unknown>(meta.params.length);
|
|
470
483
|
for (let index = 0; index < meta.params.length; index += 1) {
|
|
471
484
|
const param = meta.params[index]!;
|
|
472
|
-
const
|
|
485
|
+
const paramOptions = injectionSlotToResolveOptions(param);
|
|
473
486
|
if (param.multi) {
|
|
474
|
-
deps[index] = this.resolveAll(param.token,
|
|
487
|
+
deps[index] = this.resolveAll(param.token, paramOptions, resolutionPath, resolutionStack);
|
|
475
488
|
continue;
|
|
476
489
|
}
|
|
477
490
|
if (param.optional) {
|
|
478
|
-
deps[index] = this.resolveOptional(param.token,
|
|
491
|
+
deps[index] = this.resolveOptional(param.token, paramOptions, resolutionPath, resolutionStack);
|
|
479
492
|
continue;
|
|
480
493
|
}
|
|
481
494
|
deps[index] =
|
|
482
|
-
|
|
495
|
+
paramOptions === undefined
|
|
483
496
|
? this.resolveFromContext(param.token, resolutionPath, resolutionStack)
|
|
484
|
-
: this.resolve(param.token,
|
|
497
|
+
: this.resolve(param.token, paramOptions, resolutionPath, resolutionStack);
|
|
485
498
|
}
|
|
486
499
|
return deps;
|
|
487
500
|
}
|
|
@@ -494,11 +507,11 @@ export class DependencyResolver {
|
|
|
494
507
|
const resolved = new Array<unknown>(deps.length);
|
|
495
508
|
for (let index = 0; index < deps.length; index += 1) {
|
|
496
509
|
const dep = deps[index]!;
|
|
497
|
-
const
|
|
510
|
+
const depOptions = injectionSlotToResolveOptions(dep);
|
|
498
511
|
if (dep.multi) {
|
|
499
512
|
resolved[index] = this.resolveAll(
|
|
500
513
|
dep.token as Token<unknown> | Constructor,
|
|
501
|
-
|
|
514
|
+
depOptions,
|
|
502
515
|
resolutionPath,
|
|
503
516
|
resolutionStack,
|
|
504
517
|
);
|
|
@@ -507,40 +520,40 @@ export class DependencyResolver {
|
|
|
507
520
|
if (dep.optional) {
|
|
508
521
|
resolved[index] = this.resolveOptional(
|
|
509
522
|
dep.token as Token<unknown> | Constructor,
|
|
510
|
-
|
|
523
|
+
depOptions,
|
|
511
524
|
resolutionPath,
|
|
512
525
|
resolutionStack,
|
|
513
526
|
);
|
|
514
527
|
continue;
|
|
515
528
|
}
|
|
516
529
|
resolved[index] =
|
|
517
|
-
|
|
530
|
+
depOptions === undefined
|
|
518
531
|
? this.resolveFromContext(dep.token as Token<unknown> | Constructor, resolutionPath, resolutionStack)
|
|
519
|
-
: this.resolve(dep.token as Token<unknown> | Constructor,
|
|
532
|
+
: this.resolve(dep.token as Token<unknown> | Constructor, depOptions, resolutionPath, resolutionStack);
|
|
520
533
|
}
|
|
521
534
|
return resolved;
|
|
522
535
|
}
|
|
523
536
|
|
|
524
537
|
resolveOptional<const Value>(
|
|
525
538
|
token: Token<Value> | Constructor<Value>,
|
|
526
|
-
|
|
539
|
+
options: ResolveOptions | undefined,
|
|
527
540
|
resolutionPath: Array<string>,
|
|
528
541
|
resolutionStack: Array<ResolutionFrame>,
|
|
529
542
|
): Value | undefined {
|
|
530
|
-
if (this._findBinding(token,
|
|
543
|
+
if (this._findBinding(token, options, resolutionPath, resolutionStack) === undefined) {
|
|
531
544
|
return undefined;
|
|
532
545
|
}
|
|
533
|
-
return this.resolve(token,
|
|
546
|
+
return this.resolve(token, options, resolutionPath, resolutionStack);
|
|
534
547
|
}
|
|
535
548
|
|
|
536
549
|
resolveAll<const Value>(
|
|
537
550
|
token: Token<Value> | Constructor<Value>,
|
|
538
|
-
|
|
551
|
+
options: ResolveOptions | undefined,
|
|
539
552
|
resolutionPath: Array<string>,
|
|
540
553
|
resolutionStack: Array<ResolutionFrame>,
|
|
541
554
|
): Array<Value> {
|
|
542
|
-
if (
|
|
543
|
-
const namedCandidates = this._getSimpleNamedBindingsFromChain(token,
|
|
555
|
+
if (options?.name !== undefined && options.tag === undefined && (options.tags?.length ?? 0) === 0) {
|
|
556
|
+
const namedCandidates = this._getSimpleNamedBindingsFromChain(token, options.name);
|
|
544
557
|
if (namedCandidates.length === 0) {
|
|
545
558
|
return [];
|
|
546
559
|
}
|
|
@@ -548,7 +561,7 @@ export class DependencyResolver {
|
|
|
548
561
|
for (let index = 0; index < namedCandidates.length; index += 1) {
|
|
549
562
|
resolved[index] = this._resolveCandidateSync(
|
|
550
563
|
namedCandidates[index] as Binding<Value>,
|
|
551
|
-
|
|
564
|
+
options,
|
|
552
565
|
resolutionPath,
|
|
553
566
|
resolutionStack,
|
|
554
567
|
);
|
|
@@ -561,14 +574,14 @@ export class DependencyResolver {
|
|
|
561
574
|
return [];
|
|
562
575
|
}
|
|
563
576
|
|
|
564
|
-
const ctx = this._makeConstraintContext(resolutionPath, resolutionStack,
|
|
565
|
-
const candidates = selectAllBindings(allBindings,
|
|
577
|
+
const ctx = this._makeConstraintContext(resolutionPath, resolutionStack, options);
|
|
578
|
+
const candidates = selectAllBindings(allBindings, options, ctx);
|
|
566
579
|
|
|
567
580
|
const resolved = new Array<Value>(candidates.length);
|
|
568
581
|
for (let index = 0; index < candidates.length; index += 1) {
|
|
569
582
|
resolved[index] = this._resolveCandidateSync(
|
|
570
583
|
candidates[index] as Binding<Value>,
|
|
571
|
-
|
|
584
|
+
options,
|
|
572
585
|
resolutionPath,
|
|
573
586
|
resolutionStack,
|
|
574
587
|
);
|
|
@@ -624,16 +637,16 @@ export class DependencyResolver {
|
|
|
624
637
|
|
|
625
638
|
async resolveAsync<const Value>(
|
|
626
639
|
token: Token<Value> | Constructor<Value>,
|
|
627
|
-
|
|
640
|
+
options: ResolveOptions | undefined,
|
|
628
641
|
resolutionPath: Array<string>,
|
|
629
642
|
resolutionStack: Array<ResolutionFrame>,
|
|
630
643
|
): Promise<Value> {
|
|
631
|
-
const found = this._findBinding(token,
|
|
644
|
+
const found = this._findBinding(token, options, resolutionPath, resolutionStack);
|
|
632
645
|
|
|
633
646
|
if (found === undefined) {
|
|
634
647
|
const ownBindings = this._registry.getAll(token);
|
|
635
648
|
if (ownBindings.length > 0) {
|
|
636
|
-
throw new NoMatchingBindingError(this._getTokenName(token),
|
|
649
|
+
throw new NoMatchingBindingError(this._getTokenName(token), options ?? {}, this._getAvailableSlots(token));
|
|
637
650
|
}
|
|
638
651
|
throw new TokenNotBoundError(this._getTokenName(token));
|
|
639
652
|
}
|
|
@@ -643,7 +656,7 @@ export class DependencyResolver {
|
|
|
643
656
|
if (binding.kind === "alias") {
|
|
644
657
|
return this.resolveAsync(
|
|
645
658
|
binding.target as Token<Value> | Constructor<Value>,
|
|
646
|
-
|
|
659
|
+
options,
|
|
647
660
|
resolutionPath,
|
|
648
661
|
resolutionStack,
|
|
649
662
|
);
|
|
@@ -652,15 +665,15 @@ export class DependencyResolver {
|
|
|
652
665
|
const scope = (binding as BindingWithScope).scope ?? "transient";
|
|
653
666
|
|
|
654
667
|
if (scope === "singleton" && owner !== this) {
|
|
655
|
-
return owner._resolveBindingAsync(binding as Binding<Value>,
|
|
668
|
+
return owner._resolveBindingAsync(binding as Binding<Value>, options, resolutionPath, resolutionStack);
|
|
656
669
|
}
|
|
657
670
|
|
|
658
|
-
return this._resolveBindingAsync(binding as Binding<Value>,
|
|
671
|
+
return this._resolveBindingAsync(binding as Binding<Value>, options, resolutionPath, resolutionStack);
|
|
659
672
|
}
|
|
660
673
|
|
|
661
674
|
private async _resolveBindingAsync<const Value>(
|
|
662
675
|
binding: Binding<Value>,
|
|
663
|
-
|
|
676
|
+
options: ResolveOptions | undefined,
|
|
664
677
|
resolutionPath: Array<string>,
|
|
665
678
|
resolutionStack: Array<ResolutionFrame>,
|
|
666
679
|
): Promise<Value> {
|
|
@@ -718,7 +731,7 @@ export class DependencyResolver {
|
|
|
718
731
|
this as unknown as ResolverCallbacks,
|
|
719
732
|
resolutionPath,
|
|
720
733
|
resolutionStack,
|
|
721
|
-
|
|
734
|
+
options,
|
|
722
735
|
);
|
|
723
736
|
try {
|
|
724
737
|
if (binding.kind === "dynamic-async") {
|
|
@@ -735,7 +748,7 @@ export class DependencyResolver {
|
|
|
735
748
|
|
|
736
749
|
const needsResolutionContext = needsActivation || this._requiresResolutionContext(binding);
|
|
737
750
|
const resolutionCtx = needsResolutionContext
|
|
738
|
-
? new DefaultResolutionContext(this as unknown as ResolverCallbacks, resolutionPath, resolutionStack,
|
|
751
|
+
? new DefaultResolutionContext(this as unknown as ResolverCallbacks, resolutionPath, resolutionStack, options)
|
|
739
752
|
: undefined;
|
|
740
753
|
|
|
741
754
|
try {
|
|
@@ -856,40 +869,40 @@ export class DependencyResolver {
|
|
|
856
869
|
}
|
|
857
870
|
if (meta.params.length === 1) {
|
|
858
871
|
const param = meta.params[0]!;
|
|
859
|
-
const
|
|
872
|
+
const paramOptions = injectionSlotToResolveOptions(param);
|
|
860
873
|
if (param.multi) {
|
|
861
|
-
return [await this.resolveAllAsync(param.token,
|
|
874
|
+
return [await this.resolveAllAsync(param.token, paramOptions, resolutionPath, resolutionStack)];
|
|
862
875
|
}
|
|
863
876
|
if (param.optional) {
|
|
864
|
-
return [await this.resolveOptionalAsync(param.token,
|
|
877
|
+
return [await this.resolveOptionalAsync(param.token, paramOptions, resolutionPath, resolutionStack)];
|
|
865
878
|
}
|
|
866
|
-
if (
|
|
879
|
+
if (paramOptions === undefined) {
|
|
867
880
|
return [await this.resolveAsyncFromContext(param.token, resolutionPath, resolutionStack)];
|
|
868
881
|
}
|
|
869
|
-
return [await this.resolveAsync(param.token,
|
|
882
|
+
return [await this.resolveAsync(param.token, paramOptions, resolutionPath, resolutionStack)];
|
|
870
883
|
}
|
|
871
884
|
const pending = new Array<Promise<unknown>>(meta.params.length);
|
|
872
885
|
const shouldCloneContext = meta.params.length > 1;
|
|
873
886
|
for (let index = 0; index < meta.params.length; index += 1) {
|
|
874
887
|
const param = meta.params[index]!;
|
|
875
|
-
const
|
|
888
|
+
const paramOptions = injectionSlotToResolveOptions(param);
|
|
876
889
|
if (param.multi) {
|
|
877
890
|
pending[index] = this.resolveAllAsync(
|
|
878
891
|
param.token,
|
|
879
|
-
|
|
892
|
+
paramOptions,
|
|
880
893
|
shouldCloneContext ? [...resolutionPath] : resolutionPath,
|
|
881
894
|
shouldCloneContext ? [...resolutionStack] : resolutionStack,
|
|
882
895
|
);
|
|
883
896
|
} else if (param.optional) {
|
|
884
897
|
pending[index] = this.resolveOptionalAsync(
|
|
885
898
|
param.token,
|
|
886
|
-
|
|
899
|
+
paramOptions,
|
|
887
900
|
shouldCloneContext ? [...resolutionPath] : resolutionPath,
|
|
888
901
|
shouldCloneContext ? [...resolutionStack] : resolutionStack,
|
|
889
902
|
);
|
|
890
903
|
} else {
|
|
891
904
|
pending[index] =
|
|
892
|
-
|
|
905
|
+
paramOptions === undefined
|
|
893
906
|
? this.resolveAsyncFromContext(
|
|
894
907
|
param.token,
|
|
895
908
|
shouldCloneContext ? [...resolutionPath] : resolutionPath,
|
|
@@ -897,7 +910,7 @@ export class DependencyResolver {
|
|
|
897
910
|
)
|
|
898
911
|
: this.resolveAsync(
|
|
899
912
|
param.token,
|
|
900
|
-
|
|
913
|
+
paramOptions,
|
|
901
914
|
shouldCloneContext ? [...resolutionPath] : resolutionPath,
|
|
902
915
|
shouldCloneContext ? [...resolutionStack] : resolutionStack,
|
|
903
916
|
);
|
|
@@ -915,24 +928,24 @@ export class DependencyResolver {
|
|
|
915
928
|
const shouldCloneContext = deps.length > 1;
|
|
916
929
|
for (let index = 0; index < deps.length; index += 1) {
|
|
917
930
|
const dep = deps[index]!;
|
|
918
|
-
const
|
|
931
|
+
const depOptions = injectionSlotToResolveOptions(dep);
|
|
919
932
|
if (dep.multi) {
|
|
920
933
|
pending[index] = this.resolveAllAsync(
|
|
921
934
|
dep.token as Token<unknown> | Constructor,
|
|
922
|
-
|
|
935
|
+
depOptions,
|
|
923
936
|
shouldCloneContext ? [...resolutionPath] : resolutionPath,
|
|
924
937
|
shouldCloneContext ? [...resolutionStack] : resolutionStack,
|
|
925
938
|
);
|
|
926
939
|
} else if (dep.optional) {
|
|
927
940
|
pending[index] = this.resolveOptionalAsync(
|
|
928
941
|
dep.token as Token<unknown> | Constructor,
|
|
929
|
-
|
|
942
|
+
depOptions,
|
|
930
943
|
shouldCloneContext ? [...resolutionPath] : resolutionPath,
|
|
931
944
|
shouldCloneContext ? [...resolutionStack] : resolutionStack,
|
|
932
945
|
);
|
|
933
946
|
} else {
|
|
934
947
|
pending[index] =
|
|
935
|
-
|
|
948
|
+
depOptions === undefined
|
|
936
949
|
? this.resolveAsyncFromContext(
|
|
937
950
|
dep.token as Token<unknown> | Constructor,
|
|
938
951
|
shouldCloneContext ? [...resolutionPath] : resolutionPath,
|
|
@@ -940,7 +953,7 @@ export class DependencyResolver {
|
|
|
940
953
|
)
|
|
941
954
|
: this.resolveAsync(
|
|
942
955
|
dep.token as Token<unknown> | Constructor,
|
|
943
|
-
|
|
956
|
+
depOptions,
|
|
944
957
|
shouldCloneContext ? [...resolutionPath] : resolutionPath,
|
|
945
958
|
shouldCloneContext ? [...resolutionStack] : resolutionStack,
|
|
946
959
|
);
|
|
@@ -951,24 +964,24 @@ export class DependencyResolver {
|
|
|
951
964
|
|
|
952
965
|
async resolveOptionalAsync<const Value>(
|
|
953
966
|
token: Token<Value> | Constructor<Value>,
|
|
954
|
-
|
|
967
|
+
options: ResolveOptions | undefined,
|
|
955
968
|
resolutionPath: Array<string>,
|
|
956
969
|
resolutionStack: Array<ResolutionFrame>,
|
|
957
970
|
): Promise<Value | undefined> {
|
|
958
|
-
if (this._findBinding(token,
|
|
971
|
+
if (this._findBinding(token, options, resolutionPath, resolutionStack) === undefined) {
|
|
959
972
|
return undefined;
|
|
960
973
|
}
|
|
961
|
-
return this.resolveAsync(token,
|
|
974
|
+
return this.resolveAsync(token, options, resolutionPath, resolutionStack);
|
|
962
975
|
}
|
|
963
976
|
|
|
964
977
|
async resolveAllAsync<const Value>(
|
|
965
978
|
token: Token<Value> | Constructor<Value>,
|
|
966
|
-
|
|
979
|
+
options: ResolveOptions | undefined,
|
|
967
980
|
resolutionPath: Array<string>,
|
|
968
981
|
resolutionStack: Array<ResolutionFrame>,
|
|
969
982
|
): Promise<Array<Value>> {
|
|
970
|
-
if (
|
|
971
|
-
const namedCandidates = this._getSimpleNamedBindingsFromChain(token,
|
|
983
|
+
if (options?.name !== undefined && options.tag === undefined && (options.tags?.length ?? 0) === 0) {
|
|
984
|
+
const namedCandidates = this._getSimpleNamedBindingsFromChain(token, options.name);
|
|
972
985
|
if (namedCandidates.length === 0) {
|
|
973
986
|
return [];
|
|
974
987
|
}
|
|
@@ -976,7 +989,7 @@ export class DependencyResolver {
|
|
|
976
989
|
for (let index = 0; index < namedCandidates.length; index += 1) {
|
|
977
990
|
pending[index] = this._resolveCandidateAsync(
|
|
978
991
|
namedCandidates[index] as Binding<Value>,
|
|
979
|
-
|
|
992
|
+
options,
|
|
980
993
|
resolutionPath,
|
|
981
994
|
resolutionStack,
|
|
982
995
|
);
|
|
@@ -989,14 +1002,14 @@ export class DependencyResolver {
|
|
|
989
1002
|
return [];
|
|
990
1003
|
}
|
|
991
1004
|
|
|
992
|
-
const ctx = this._makeConstraintContext(resolutionPath, resolutionStack,
|
|
993
|
-
const candidates = selectAllBindings(allBindings,
|
|
1005
|
+
const ctx = this._makeConstraintContext(resolutionPath, resolutionStack, options);
|
|
1006
|
+
const candidates = selectAllBindings(allBindings, options, ctx);
|
|
994
1007
|
|
|
995
1008
|
const pending = new Array<Promise<Value>>(candidates.length);
|
|
996
1009
|
for (let index = 0; index < candidates.length; index += 1) {
|
|
997
1010
|
pending[index] = this._resolveCandidateAsync(
|
|
998
1011
|
candidates[index] as Binding<Value>,
|
|
999
|
-
|
|
1012
|
+
options,
|
|
1000
1013
|
resolutionPath,
|
|
1001
1014
|
resolutionStack,
|
|
1002
1015
|
);
|
|
@@ -1050,9 +1063,9 @@ export class DependencyResolver {
|
|
|
1050
1063
|
private _makeConstraintContext(
|
|
1051
1064
|
resolutionPath: Array<string>,
|
|
1052
1065
|
resolutionStack: Array<ResolutionFrame>,
|
|
1053
|
-
|
|
1066
|
+
options: ResolveOptions | undefined,
|
|
1054
1067
|
): ConstraintContext {
|
|
1055
|
-
if (
|
|
1068
|
+
if (options === undefined && resolutionPath.length === 0 && resolutionStack.length === 0) {
|
|
1056
1069
|
return ROOT_CONSTRAINT_CONTEXT;
|
|
1057
1070
|
}
|
|
1058
1071
|
const parent = resolutionStack.at(-1);
|
|
@@ -1062,50 +1075,50 @@ export class DependencyResolver {
|
|
|
1062
1075
|
resolutionStack,
|
|
1063
1076
|
parent,
|
|
1064
1077
|
ancestors,
|
|
1065
|
-
|
|
1078
|
+
currentResolveOptions: options,
|
|
1066
1079
|
};
|
|
1067
1080
|
}
|
|
1068
1081
|
|
|
1069
1082
|
private _matchesBindingFast(
|
|
1070
1083
|
binding: Binding,
|
|
1071
|
-
|
|
1084
|
+
options: ResolveOptions | undefined,
|
|
1072
1085
|
resolutionPath: Array<string>,
|
|
1073
1086
|
resolutionStack: Array<ResolutionFrame>,
|
|
1074
1087
|
): boolean {
|
|
1075
|
-
if (!this._matchesSlotFast(binding.slot,
|
|
1088
|
+
if (!this._matchesSlotFast(binding.slot, options)) {
|
|
1076
1089
|
return false;
|
|
1077
1090
|
}
|
|
1078
1091
|
if (binding.predicate === undefined) {
|
|
1079
1092
|
return true;
|
|
1080
1093
|
}
|
|
1081
|
-
const ctx = this._makeConstraintContext(resolutionPath, resolutionStack,
|
|
1094
|
+
const ctx = this._makeConstraintContext(resolutionPath, resolutionStack, options);
|
|
1082
1095
|
return binding.predicate(ctx);
|
|
1083
1096
|
}
|
|
1084
1097
|
|
|
1085
|
-
private _matchesSlotFast(slot: BindingSlot,
|
|
1086
|
-
const
|
|
1087
|
-
const
|
|
1088
|
-
const
|
|
1089
|
-
const
|
|
1098
|
+
private _matchesSlotFast(slot: BindingSlot, options: ResolveOptions | undefined): boolean {
|
|
1099
|
+
const requestedName = options?.name;
|
|
1100
|
+
const requestedTags = options?.tags;
|
|
1101
|
+
const singleRequestedTag = options?.tag;
|
|
1102
|
+
const hasRequestedTags = (requestedTags?.length ?? 0) > 0 || singleRequestedTag !== undefined;
|
|
1090
1103
|
|
|
1091
1104
|
if (slot.name !== undefined) {
|
|
1092
|
-
if (
|
|
1105
|
+
if (requestedName === undefined || slot.name !== requestedName) {
|
|
1093
1106
|
return false;
|
|
1094
1107
|
}
|
|
1095
|
-
} else if (
|
|
1108
|
+
} else if (requestedName !== undefined) {
|
|
1096
1109
|
return false;
|
|
1097
1110
|
}
|
|
1098
1111
|
|
|
1099
1112
|
if (slot.tags.length > 0) {
|
|
1100
|
-
if (!
|
|
1113
|
+
if (!hasRequestedTags) {
|
|
1101
1114
|
return false;
|
|
1102
1115
|
}
|
|
1103
1116
|
for (const [tagKey, tagValue] of slot.tags) {
|
|
1104
|
-
if (!this.
|
|
1117
|
+
if (!this._matchesRequestedTag(tagKey, tagValue, requestedTags, singleRequestedTag)) {
|
|
1105
1118
|
return false;
|
|
1106
1119
|
}
|
|
1107
1120
|
}
|
|
1108
|
-
} else if (
|
|
1121
|
+
} else if (hasRequestedTags) {
|
|
1109
1122
|
return false;
|
|
1110
1123
|
}
|
|
1111
1124
|
|
|
@@ -1140,21 +1153,25 @@ export class DependencyResolver {
|
|
|
1140
1153
|
return runWithContainer(this._container, () => new invokable(...deps));
|
|
1141
1154
|
}
|
|
1142
1155
|
|
|
1143
|
-
private
|
|
1156
|
+
private _matchesRequestedTag(
|
|
1144
1157
|
tagKey: string,
|
|
1145
1158
|
tagValue: unknown,
|
|
1146
|
-
|
|
1147
|
-
|
|
1159
|
+
requestedTags: ReadonlyArray<BindingTag> | undefined,
|
|
1160
|
+
singleRequestedTag: BindingTag | undefined,
|
|
1148
1161
|
): boolean {
|
|
1149
|
-
if (
|
|
1162
|
+
if (
|
|
1163
|
+
singleRequestedTag !== undefined &&
|
|
1164
|
+
singleRequestedTag[0] === tagKey &&
|
|
1165
|
+
Object.is(singleRequestedTag[1], tagValue)
|
|
1166
|
+
) {
|
|
1150
1167
|
return true;
|
|
1151
1168
|
}
|
|
1152
|
-
if (
|
|
1169
|
+
if (requestedTags === undefined || requestedTags.length === 0) {
|
|
1153
1170
|
return false;
|
|
1154
1171
|
}
|
|
1155
|
-
for (let index = 0; index <
|
|
1156
|
-
const
|
|
1157
|
-
if (
|
|
1172
|
+
for (let index = 0; index < requestedTags.length; index += 1) {
|
|
1173
|
+
const requestedTag = requestedTags[index]!;
|
|
1174
|
+
if (requestedTag[0] === tagKey && Object.is(requestedTag[1], tagValue)) {
|
|
1158
1175
|
return true;
|
|
1159
1176
|
}
|
|
1160
1177
|
}
|
|
@@ -1445,7 +1462,7 @@ export class DependencyResolver {
|
|
|
1445
1462
|
|
|
1446
1463
|
private _resolveCandidateSync<const Value>(
|
|
1447
1464
|
binding: Binding<Value>,
|
|
1448
|
-
|
|
1465
|
+
options: ResolveOptions | undefined,
|
|
1449
1466
|
resolutionPath: Array<string>,
|
|
1450
1467
|
resolutionStack: Array<ResolutionFrame>,
|
|
1451
1468
|
): Value {
|
|
@@ -1457,7 +1474,7 @@ export class DependencyResolver {
|
|
|
1457
1474
|
return binding.value;
|
|
1458
1475
|
}
|
|
1459
1476
|
if (binding.kind === "alias") {
|
|
1460
|
-
return this.resolve(binding.target,
|
|
1477
|
+
return this.resolve(binding.target, options, resolutionPath, resolutionStack);
|
|
1461
1478
|
}
|
|
1462
1479
|
const scope = (binding as BindingWithScope).scope ?? "transient";
|
|
1463
1480
|
if (scope === "singleton" && this._scope.hasSingleton(binding.id)) {
|
|
@@ -1471,12 +1488,12 @@ export class DependencyResolver {
|
|
|
1471
1488
|
return this._scope.getScoped<Value>(binding.id);
|
|
1472
1489
|
}
|
|
1473
1490
|
}
|
|
1474
|
-
return this._resolveBinding(binding,
|
|
1491
|
+
return this._resolveBinding(binding, options, resolutionPath, resolutionStack);
|
|
1475
1492
|
}
|
|
1476
1493
|
|
|
1477
1494
|
private _resolveCandidateAsync<const Value>(
|
|
1478
1495
|
binding: Binding<Value>,
|
|
1479
|
-
|
|
1496
|
+
options: ResolveOptions | undefined,
|
|
1480
1497
|
resolutionPath: Array<string>,
|
|
1481
1498
|
resolutionStack: Array<ResolutionFrame>,
|
|
1482
1499
|
): Promise<Value> {
|
|
@@ -1490,7 +1507,7 @@ export class DependencyResolver {
|
|
|
1490
1507
|
const isolatedPath = [...resolutionPath];
|
|
1491
1508
|
const isolatedStack = [...resolutionStack];
|
|
1492
1509
|
if (binding.kind === "alias") {
|
|
1493
|
-
return this.resolveAsync(binding.target,
|
|
1510
|
+
return this.resolveAsync(binding.target, options, isolatedPath, isolatedStack);
|
|
1494
1511
|
}
|
|
1495
1512
|
const scope = (binding as BindingWithScope).scope ?? "transient";
|
|
1496
1513
|
if (scope === "singleton" && this._scope.hasSingleton(binding.id)) {
|
|
@@ -1504,7 +1521,7 @@ export class DependencyResolver {
|
|
|
1504
1521
|
return Promise.resolve(this._scope.getScoped<Value>(binding.id));
|
|
1505
1522
|
}
|
|
1506
1523
|
}
|
|
1507
|
-
return this._resolveBindingAsync(binding,
|
|
1524
|
+
return this._resolveBindingAsync(binding, options, isolatedPath, isolatedStack);
|
|
1508
1525
|
}
|
|
1509
1526
|
|
|
1510
1527
|
private _getResolutionFrame<const Value>(binding: Binding<Value>): ResolutionFrame {
|
|
@@ -1589,19 +1606,19 @@ export class DependencyResolver {
|
|
|
1589
1606
|
private _acquireSyncResolutionContext(
|
|
1590
1607
|
resolutionPath: Array<string>,
|
|
1591
1608
|
resolutionStack: Array<ResolutionFrame>,
|
|
1592
|
-
|
|
1609
|
+
options: ResolveOptions | undefined,
|
|
1593
1610
|
): DefaultResolutionContext {
|
|
1594
1611
|
const depth = resolutionStack.length;
|
|
1595
1612
|
const existing = this._syncResolutionContextPool[depth];
|
|
1596
1613
|
if (existing !== undefined) {
|
|
1597
|
-
existing.reset(this as unknown as ResolverCallbacks, resolutionPath, resolutionStack,
|
|
1614
|
+
existing.reset(this as unknown as ResolverCallbacks, resolutionPath, resolutionStack, options);
|
|
1598
1615
|
return existing;
|
|
1599
1616
|
}
|
|
1600
1617
|
const created = new DefaultResolutionContext(
|
|
1601
1618
|
this as unknown as ResolverCallbacks,
|
|
1602
1619
|
resolutionPath,
|
|
1603
1620
|
resolutionStack,
|
|
1604
|
-
|
|
1621
|
+
options,
|
|
1605
1622
|
);
|
|
1606
1623
|
this._syncResolutionContextPool[depth] = created;
|
|
1607
1624
|
return created;
|