@zudojs/container 1.2.0 → 1.2.2
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/README.md
CHANGED
|
@@ -162,9 +162,13 @@ container.register(API, {
|
|
|
162
162
|
});
|
|
163
163
|
```
|
|
164
164
|
|
|
165
|
-
Classes without an `inject` list are constructed with zero arguments
|
|
166
|
-
|
|
167
|
-
|
|
165
|
+
Classes without an `inject` list are constructed with zero arguments, so
|
|
166
|
+
only a constructor that declares no parameters may omit it (parameters with
|
|
167
|
+
a default value do not count). Registering such a class without `inject`
|
|
168
|
+
is allowed, but resolving it throws a `ProviderResolutionError` naming the
|
|
169
|
+
class and the `inject: [...]` fix, instead of building it with `undefined`
|
|
170
|
+
dependencies. There is no reflection/decorator magic — dependencies are
|
|
171
|
+
exactly the tokens you list, resolved in order.
|
|
168
172
|
|
|
169
173
|
## Duplicate registrations
|
|
170
174
|
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* @zudojs/container/containerResolution/containerResolution.autoRegister
|
|
3
3
|
*
|
|
4
|
-
* Guards
|
|
5
|
-
*
|
|
6
|
-
*
|
|
4
|
+
* Guards against building a class with no arguments when its constructor
|
|
5
|
+
* declares some: an unregistered class under `autoRegisterClasses`, and a
|
|
6
|
+
* class registration with no `inject` list.
|
|
7
7
|
*/
|
|
8
8
|
/**
|
|
9
9
|
* Whether an unregistered token may be auto-registered: a class whose
|
|
@@ -24,4 +24,19 @@ export declare function isAutoRegistrable(token: unknown): boolean;
|
|
|
24
24
|
export declare function assertAutoRegistrable(token: {
|
|
25
25
|
readonly length: number;
|
|
26
26
|
}): void;
|
|
27
|
+
/**
|
|
28
|
+
* Throws when a class registration has no `inject` list but its constructor
|
|
29
|
+
* declares parameters. Without one the class is built with no arguments,
|
|
30
|
+
* so every dependency would be `undefined`. Registering it is allowed;
|
|
31
|
+
* resolving it is what fails.
|
|
32
|
+
*
|
|
33
|
+
* Parameters with a default value do not count (`Function.length` stops at
|
|
34
|
+
* the first one).
|
|
35
|
+
*
|
|
36
|
+
* @throws {ProviderResolutionError} naming the class and the `inject` fix.
|
|
37
|
+
*/
|
|
38
|
+
export declare function assertClassInjectable(token: string, ctor: {
|
|
39
|
+
readonly length: number;
|
|
40
|
+
readonly name: string;
|
|
41
|
+
}, inject: readonly unknown[]): void;
|
|
27
42
|
//# sourceMappingURL=containerResolution.autoRegister.d.ts.map
|
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* @zudojs/container/containerResolution/containerResolution.autoRegister
|
|
3
3
|
*
|
|
4
|
-
* Guards
|
|
5
|
-
*
|
|
6
|
-
*
|
|
4
|
+
* Guards against building a class with no arguments when its constructor
|
|
5
|
+
* declares some: an unregistered class under `autoRegisterClasses`, and a
|
|
6
|
+
* class registration with no `inject` list.
|
|
7
7
|
*/
|
|
8
|
-
import { RegistrationNotFoundError } from "@zudojs/errors";
|
|
8
|
+
import { ProviderResolutionError, RegistrationNotFoundError, } from "@zudojs/errors";
|
|
9
9
|
import { describeToken } from "../containerToken/containerToken.type.js";
|
|
10
10
|
/**
|
|
11
11
|
* Whether an unregistered token may be auto-registered: a class whose
|
|
@@ -37,4 +37,26 @@ export function assertAutoRegistrable(token) {
|
|
|
37
37
|
`{ inject: [/* one token per parameter */] }) or ` +
|
|
38
38
|
`container.registerFactory(${name}, (...deps) => new ${name}(...deps), [/* tokens */]).`);
|
|
39
39
|
}
|
|
40
|
+
/**
|
|
41
|
+
* Throws when a class registration has no `inject` list but its constructor
|
|
42
|
+
* declares parameters. Without one the class is built with no arguments,
|
|
43
|
+
* so every dependency would be `undefined`. Registering it is allowed;
|
|
44
|
+
* resolving it is what fails.
|
|
45
|
+
*
|
|
46
|
+
* Parameters with a default value do not count (`Function.length` stops at
|
|
47
|
+
* the first one).
|
|
48
|
+
*
|
|
49
|
+
* @throws {ProviderResolutionError} naming the class and the `inject` fix.
|
|
50
|
+
*/
|
|
51
|
+
export function assertClassInjectable(token, ctor, inject) {
|
|
52
|
+
const count = ctor.length;
|
|
53
|
+
if (inject.length > 0 || count === 0)
|
|
54
|
+
return;
|
|
55
|
+
const name = ctor.name || "anonymous class";
|
|
56
|
+
throw new ProviderResolutionError(token, `Cannot build class "${name}" for token "${token}": its constructor ` +
|
|
57
|
+
`declares ${count} parameter${count === 1 ? "" : "s"} and the ` +
|
|
58
|
+
`registration has no inject list, so it would be built with undefined ` +
|
|
59
|
+
`dependencies. Register it with container.registerClass(${token}, ` +
|
|
60
|
+
`${name}, { inject: [/* one token per parameter */] }).`);
|
|
61
|
+
}
|
|
40
62
|
//# sourceMappingURL=containerResolution.autoRegister.js.map
|
|
@@ -35,7 +35,7 @@ import { unwrapToken } from "../containerToken/containerToken.type.js";
|
|
|
35
35
|
import { CircularDependencyError, ContainerError, ProviderResolutionError, RegistrationNotFoundError, } from "@zudojs/errors";
|
|
36
36
|
import { AsyncProviderError, CaptiveDependencyError, DependencyResolutionError, MaxResolutionDepthError, ScopedResolutionError, } from "./containerResolution.error.js";
|
|
37
37
|
import { describeToken } from "../containerToken/containerToken.type.js";
|
|
38
|
-
import { assertAutoRegistrable, isAutoRegistrable, } from "./containerResolution.autoRegister.js";
|
|
38
|
+
import { assertAutoRegistrable, assertClassInjectable, isAutoRegistrable, } from "./containerResolution.autoRegister.js";
|
|
39
39
|
import { DependentIndex } from "./containerResolution.dependents.js";
|
|
40
40
|
/**
|
|
41
41
|
* Scope cache that falls back to its parent scope's cache for lookups while
|
|
@@ -239,6 +239,7 @@ export class ContainerResolver {
|
|
|
239
239
|
}
|
|
240
240
|
if (isClassProvider(provider)) {
|
|
241
241
|
const deps = provider.inject ?? [];
|
|
242
|
+
assertClassInjectable(describeToken(token), provider.useClass, deps);
|
|
242
243
|
const args = deps.map((d) => this.resolveInternal(unwrapToken(d), state, singletonAncestor)
|
|
243
244
|
.value);
|
|
244
245
|
const ctor = provider.useClass;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@zudojs/container",
|
|
3
|
-
"version": "1.2.
|
|
3
|
+
"version": "1.2.2",
|
|
4
4
|
"description": "Token-based dependency injection container for managing application dependencies and service lifetimes.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "./dist/index.js",
|
|
@@ -18,7 +18,7 @@
|
|
|
18
18
|
"!dist/.tsbuildinfo"
|
|
19
19
|
],
|
|
20
20
|
"dependencies": {
|
|
21
|
-
"@zudojs/errors": "1.3.
|
|
21
|
+
"@zudojs/errors": "1.3.1"
|
|
22
22
|
},
|
|
23
23
|
"devDependencies": {
|
|
24
24
|
"typescript": "7.0.2",
|