Skip to content

Commit 737fabe

Browse files
committed
feat: explicit injection context in inheritance helpers
1 parent 2c04bbe commit 737fabe

4 files changed

Lines changed: 35 additions & 8 deletions

File tree

.vscode/symbols.json

Lines changed: 1 addition & 1 deletion
Large diffs are not rendered by default.

docs/API.md

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -387,14 +387,16 @@ function injectAsync<T>(
387387
options?: {
388388
withCache?: boolean;
389389
overrides?: Provider[];
390+
injector?: iInjector;
390391
}
391392
): () => Promise<T | T[]>
392393
```
393394

394-
| Option | Type | Default | Description |
395-
| ----------- | ------------ | ------- | ------------------------------------------ |
396-
| `withCache` | `boolean` | `true` | Cache the resolved instance |
397-
| `overrides` | `Provider[]` | `[]` | Additional providers for the sub-container |
395+
| Option | Type | Default | Description |
396+
| ----------- | ------------ | ----------- | ------------------------------------------ |
397+
| `withCache` | `boolean` | `true` | Cache the resolved instance |
398+
| `overrides` | `Provider[]` | `[]` | Additional providers for the sub-container |
399+
| `injector` | `iInjector` | `undefined` | Explicit injector to use instead of context|
398400

399401
```typescript
400402
private readonly getAnalytics = injectAsync(
@@ -417,6 +419,7 @@ function injectGroupAsync(
417419
options?: {
418420
withCache?: boolean;
419421
overrides?: Provider[];
422+
injector?: iInjector;
420423
}
421424
): () => Promise<iInjector>
422425
```
@@ -442,6 +445,7 @@ function injectEntryAsync<T>(
442445
options?: {
443446
withCache?: boolean;
444447
overrides?: Provider[];
448+
injector?: iInjector;
445449
}
446450
): () => Promise<T | T[]>
447451
```

docs/ASYNC_INJECTION.md

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ This guide covers advanced dependency injection patterns using `injectAsync`, `i
77
- [🔗 Async Injection \& Sub-Containers](#-async-injection--sub-containers)
88
- [Table of contents](#table-of-contents)
99
- [Overview](#overview)
10+
- [Explicit Injector Context](#explicit-injector-context)
1011
- [injectAsync](#injectasync)
1112
- [Basic usage](#basic-usage)
1213
- [Use cases](#use-cases)
@@ -55,6 +56,20 @@ All utilities support:
5556
- ✅ Full type inference
5657
- ✅ Dependency overrides
5758
- ✅ Parent container access
59+
- ✅ Optional explicit injector context
60+
61+
### Explicit Injector Context
62+
63+
By default, `injectAsync` inherits from the injector of the current context. You can manually specify a parent injector using the `injector` option. This is useful when creating factories outside of the injection context or when you want to use a specific injector instance.
64+
65+
```typescript
66+
const getService = injectAsync(
67+
async () => MyService,
68+
{ injector: myParentInjector }
69+
);
70+
71+
const service = await getService();
72+
```
5873

5974
## injectAsync
6075

src/lib/utils/inheritance.ts

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -14,12 +14,20 @@ interface iInjectionOptions {
1414
* @default true
1515
*/
1616
withCache?: boolean;
17+
1718
/**
1819
* Overrides to provide to the sub-container
1920
* These will be provided in addition to the main injection
2021
* @default []
2122
*/
2223
overrides?: Provider[];
24+
25+
/**
26+
* Allows to use the function with specified injector outside of Injection Context.
27+
* By default, the injector is obtained from the current injection context.
28+
* @default undefined
29+
*/
30+
injector?: iInjector;
2331
}
2432

2533
/**
@@ -37,7 +45,7 @@ export function injectGroupAsync(
3745
fn: MaybeAsyncFactory<Provider[]>,
3846
opts?: iInjectionOptions,
3947
): () => Promise<iInjector> {
40-
const { container: parent } = nodeInject(Injector);
48+
const { container: parent } = opts?.injector ?? nodeInject(Injector);
4149
const factory = async () => {
4250
const providers = await fn();
4351

@@ -88,7 +96,7 @@ export function injectAsync<T>(
8896
fn: MaybeAsyncFactory<Token<T>>,
8997
opts?: iInjectionOptions,
9098
): () => Promise<T | T[]> {
91-
const { container: parent } = nodeInject(Injector);
99+
const { container: parent } = opts?.injector ?? nodeInject(Injector);
92100
const factory = (async () => {
93101
const token = await fn();
94102
const tempContainer = new NodeContainer({ parent });
@@ -143,7 +151,7 @@ export function injectEntryAsync<T>(
143151
fn: MaybeAsyncFactory<iEntrypointConfig<Token<T>>>,
144152
opts?: iInjectionOptions,
145153
): () => Promise<T | T[]> {
146-
const { container: parent } = nodeInject(Injector);
154+
const { container: parent } = opts?.injector ?? nodeInject(Injector);
147155
const factory = (async () => {
148156
const { entrypoint, providers } = await fn();
149157

0 commit comments

Comments
 (0)