ts-ioc-container 37.2.0 → 37.3.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/cjm/container/AutoMockedContainer.js +3 -0
- package/cjm/container/Container.js +33 -16
- package/cjm/container/EmptyContainer.js +3 -0
- package/cjm/hooks/HookContext.js +0 -4
- package/esm/container/AutoMockedContainer.js +3 -0
- package/esm/container/Container.js +33 -16
- package/esm/container/EmptyContainer.js +3 -0
- package/esm/hooks/HookContext.js +0 -4
- package/package.json +3 -2
- package/typings/container/AutoMockedContainer.d.ts +1 -0
- package/typings/container/Container.d.ts +5 -2
- package/typings/container/EmptyContainer.d.ts +1 -0
- package/typings/container/IContainer.d.ts +4 -1
- package/typings/hooks/HookContext.d.ts +0 -2
|
@@ -8,17 +8,17 @@ class Container {
|
|
|
8
8
|
constructor(injector, options = {}) {
|
|
9
9
|
this.injector = injector;
|
|
10
10
|
this.isDisposed = false;
|
|
11
|
-
this.scopes =
|
|
12
|
-
this.instances =
|
|
11
|
+
this.scopes = [];
|
|
12
|
+
this.instances = [];
|
|
13
13
|
this.providers = new Map();
|
|
14
|
-
this.registrations =
|
|
14
|
+
this.registrations = [];
|
|
15
15
|
this.parent = options.parent ?? new EmptyContainer_1.EmptyContainer();
|
|
16
16
|
this.tags = new Set(options.tags ?? []);
|
|
17
17
|
this.onConstruct = options.onConstruct ?? (() => { });
|
|
18
18
|
this.onDispose = options.onDispose ?? (() => { });
|
|
19
19
|
}
|
|
20
20
|
add(registration) {
|
|
21
|
-
this.registrations.
|
|
21
|
+
this.registrations.push(registration);
|
|
22
22
|
registration.applyTo(this);
|
|
23
23
|
return this;
|
|
24
24
|
}
|
|
@@ -31,8 +31,8 @@ class Container {
|
|
|
31
31
|
this.validateContainer();
|
|
32
32
|
if ((0, IContainer_1.isConstructor)(token)) {
|
|
33
33
|
const instance = this.injector.resolve(this, token, { args });
|
|
34
|
-
this.instances.
|
|
35
|
-
this.onConstruct(instance);
|
|
34
|
+
this.instances.push(instance);
|
|
35
|
+
this.onConstruct(instance, this);
|
|
36
36
|
return instance;
|
|
37
37
|
}
|
|
38
38
|
const provider = this.providers.get(token);
|
|
@@ -44,7 +44,7 @@ class Container {
|
|
|
44
44
|
this.validateContainer();
|
|
45
45
|
const scope = new Container(this.injector, { parent: this, tags, onDispose: this.onDispose });
|
|
46
46
|
scope.applyRegistrationsFrom(this);
|
|
47
|
-
this.scopes.
|
|
47
|
+
this.scopes.push(scope);
|
|
48
48
|
return scope;
|
|
49
49
|
}
|
|
50
50
|
dispose({ cascade = true } = {}) {
|
|
@@ -55,16 +55,24 @@ class Container {
|
|
|
55
55
|
this.parent = new EmptyContainer_1.EmptyContainer();
|
|
56
56
|
// Reset the state
|
|
57
57
|
this.providers.clear();
|
|
58
|
-
this.instances.
|
|
59
|
-
this.registrations.
|
|
58
|
+
this.instances.splice(0, this.instances.length);
|
|
59
|
+
this.registrations.splice(0, this.registrations.length);
|
|
60
60
|
this.onDispose(this);
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
61
|
+
// Dispose all scopes
|
|
62
|
+
while (this.scopes.length > 0) {
|
|
63
|
+
const scope = this.scopes[0];
|
|
64
|
+
if (cascade) {
|
|
65
|
+
scope.dispose({ cascade: true });
|
|
66
|
+
}
|
|
67
|
+
else {
|
|
68
|
+
scope.detachFromParent();
|
|
65
69
|
}
|
|
66
70
|
}
|
|
67
71
|
}
|
|
72
|
+
detachFromParent() {
|
|
73
|
+
this.parent.removeScope(this);
|
|
74
|
+
this.parent = new EmptyContainer_1.EmptyContainer();
|
|
75
|
+
}
|
|
68
76
|
use(module) {
|
|
69
77
|
module.applyTo(this);
|
|
70
78
|
return this;
|
|
@@ -94,8 +102,16 @@ class Container {
|
|
|
94
102
|
getScopes() {
|
|
95
103
|
return [...this.scopes];
|
|
96
104
|
}
|
|
97
|
-
getInstances() {
|
|
98
|
-
|
|
105
|
+
getInstances({ cascade = true } = {}) {
|
|
106
|
+
const result = [...this.instances];
|
|
107
|
+
if (cascade) {
|
|
108
|
+
for (const scope of this.scopes) {
|
|
109
|
+
for (const instance of scope.getInstances({ cascade })) {
|
|
110
|
+
result.push(instance);
|
|
111
|
+
}
|
|
112
|
+
}
|
|
113
|
+
}
|
|
114
|
+
return result;
|
|
99
115
|
}
|
|
100
116
|
hasTag(tag) {
|
|
101
117
|
return this.tags.has(tag);
|
|
@@ -118,7 +134,8 @@ class Container {
|
|
|
118
134
|
* @private
|
|
119
135
|
*/
|
|
120
136
|
removeScope(child) {
|
|
121
|
-
this.scopes.
|
|
137
|
+
const index = this.scopes.indexOf(child);
|
|
138
|
+
this.scopes.splice(index, 1);
|
|
122
139
|
}
|
|
123
140
|
validateContainer() {
|
|
124
141
|
ContainerDisposedError_1.ContainerDisposedError.assert(!this.isDisposed, 'Container is already disposed');
|
package/cjm/hooks/HookContext.js
CHANGED
|
@@ -19,10 +19,6 @@ class HookContext {
|
|
|
19
19
|
// @ts-ignore
|
|
20
20
|
this.instance[this.methodName] = fn(this.scope);
|
|
21
21
|
}
|
|
22
|
-
getProperty() {
|
|
23
|
-
// @ts-ignore
|
|
24
|
-
return this.instance[this.methodName];
|
|
25
|
-
}
|
|
26
22
|
}
|
|
27
23
|
exports.HookContext = HookContext;
|
|
28
24
|
const createHookContext = (Target, scope, methodName = 'constructor') => new HookContext(Target, scope, methodName);
|
|
@@ -5,17 +5,17 @@ export class Container {
|
|
|
5
5
|
constructor(injector, options = {}) {
|
|
6
6
|
this.injector = injector;
|
|
7
7
|
this.isDisposed = false;
|
|
8
|
-
this.scopes =
|
|
9
|
-
this.instances =
|
|
8
|
+
this.scopes = [];
|
|
9
|
+
this.instances = [];
|
|
10
10
|
this.providers = new Map();
|
|
11
|
-
this.registrations =
|
|
11
|
+
this.registrations = [];
|
|
12
12
|
this.parent = options.parent ?? new EmptyContainer();
|
|
13
13
|
this.tags = new Set(options.tags ?? []);
|
|
14
14
|
this.onConstruct = options.onConstruct ?? (() => { });
|
|
15
15
|
this.onDispose = options.onDispose ?? (() => { });
|
|
16
16
|
}
|
|
17
17
|
add(registration) {
|
|
18
|
-
this.registrations.
|
|
18
|
+
this.registrations.push(registration);
|
|
19
19
|
registration.applyTo(this);
|
|
20
20
|
return this;
|
|
21
21
|
}
|
|
@@ -28,8 +28,8 @@ export class Container {
|
|
|
28
28
|
this.validateContainer();
|
|
29
29
|
if (isConstructor(token)) {
|
|
30
30
|
const instance = this.injector.resolve(this, token, { args });
|
|
31
|
-
this.instances.
|
|
32
|
-
this.onConstruct(instance);
|
|
31
|
+
this.instances.push(instance);
|
|
32
|
+
this.onConstruct(instance, this);
|
|
33
33
|
return instance;
|
|
34
34
|
}
|
|
35
35
|
const provider = this.providers.get(token);
|
|
@@ -41,7 +41,7 @@ export class Container {
|
|
|
41
41
|
this.validateContainer();
|
|
42
42
|
const scope = new Container(this.injector, { parent: this, tags, onDispose: this.onDispose });
|
|
43
43
|
scope.applyRegistrationsFrom(this);
|
|
44
|
-
this.scopes.
|
|
44
|
+
this.scopes.push(scope);
|
|
45
45
|
return scope;
|
|
46
46
|
}
|
|
47
47
|
dispose({ cascade = true } = {}) {
|
|
@@ -52,16 +52,24 @@ export class Container {
|
|
|
52
52
|
this.parent = new EmptyContainer();
|
|
53
53
|
// Reset the state
|
|
54
54
|
this.providers.clear();
|
|
55
|
-
this.instances.
|
|
56
|
-
this.registrations.
|
|
55
|
+
this.instances.splice(0, this.instances.length);
|
|
56
|
+
this.registrations.splice(0, this.registrations.length);
|
|
57
57
|
this.onDispose(this);
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
58
|
+
// Dispose all scopes
|
|
59
|
+
while (this.scopes.length > 0) {
|
|
60
|
+
const scope = this.scopes[0];
|
|
61
|
+
if (cascade) {
|
|
62
|
+
scope.dispose({ cascade: true });
|
|
63
|
+
}
|
|
64
|
+
else {
|
|
65
|
+
scope.detachFromParent();
|
|
62
66
|
}
|
|
63
67
|
}
|
|
64
68
|
}
|
|
69
|
+
detachFromParent() {
|
|
70
|
+
this.parent.removeScope(this);
|
|
71
|
+
this.parent = new EmptyContainer();
|
|
72
|
+
}
|
|
65
73
|
use(module) {
|
|
66
74
|
module.applyTo(this);
|
|
67
75
|
return this;
|
|
@@ -91,8 +99,16 @@ export class Container {
|
|
|
91
99
|
getScopes() {
|
|
92
100
|
return [...this.scopes];
|
|
93
101
|
}
|
|
94
|
-
getInstances() {
|
|
95
|
-
|
|
102
|
+
getInstances({ cascade = true } = {}) {
|
|
103
|
+
const result = [...this.instances];
|
|
104
|
+
if (cascade) {
|
|
105
|
+
for (const scope of this.scopes) {
|
|
106
|
+
for (const instance of scope.getInstances({ cascade })) {
|
|
107
|
+
result.push(instance);
|
|
108
|
+
}
|
|
109
|
+
}
|
|
110
|
+
}
|
|
111
|
+
return result;
|
|
96
112
|
}
|
|
97
113
|
hasTag(tag) {
|
|
98
114
|
return this.tags.has(tag);
|
|
@@ -115,7 +131,8 @@ export class Container {
|
|
|
115
131
|
* @private
|
|
116
132
|
*/
|
|
117
133
|
removeScope(child) {
|
|
118
|
-
this.scopes.
|
|
134
|
+
const index = this.scopes.indexOf(child);
|
|
135
|
+
this.scopes.splice(index, 1);
|
|
119
136
|
}
|
|
120
137
|
validateContainer() {
|
|
121
138
|
ContainerDisposedError.assert(!this.isDisposed, 'Container is already disposed');
|
package/esm/hooks/HookContext.js
CHANGED
|
@@ -16,10 +16,6 @@ export class HookContext {
|
|
|
16
16
|
// @ts-ignore
|
|
17
17
|
this.instance[this.methodName] = fn(this.scope);
|
|
18
18
|
}
|
|
19
|
-
getProperty() {
|
|
20
|
-
// @ts-ignore
|
|
21
|
-
return this.instance[this.methodName];
|
|
22
|
-
}
|
|
23
19
|
}
|
|
24
20
|
export const createHookContext = (Target, scope, methodName = 'constructor') => new HookContext(Target, scope, methodName);
|
|
25
21
|
export const hookMetaKey = (methodName = 'constructor') => `inject:${methodName}`;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "ts-ioc-container",
|
|
3
|
-
"version": "37.
|
|
3
|
+
"version": "37.3.0",
|
|
4
4
|
"description": "Typescript IoC container",
|
|
5
5
|
"publishConfig": {
|
|
6
6
|
"access": "public",
|
|
@@ -51,7 +51,8 @@
|
|
|
51
51
|
"format": "prettier --write \"**/*.ts\"",
|
|
52
52
|
"lint": "eslint lib/**/*.ts __tests__/**/*.ts scripts/**/*.ts",
|
|
53
53
|
"lint:fix": "npm run lint --fix",
|
|
54
|
-
"prepare": "husky"
|
|
54
|
+
"prepare": "husky",
|
|
55
|
+
"release": "npm run build && npm test && npm publish"
|
|
55
56
|
},
|
|
56
57
|
"devDependencies": {
|
|
57
58
|
"@types/jest": "29.5.14",
|
|
@@ -6,6 +6,7 @@ export declare abstract class AutoMockedContainer implements IContainer {
|
|
|
6
6
|
createScope(): IContainer;
|
|
7
7
|
abstract resolve<T>(key: InjectionToken<T>, options?: ResolveOptions): T;
|
|
8
8
|
dispose(): void;
|
|
9
|
+
detachFromParent(): void;
|
|
9
10
|
register(): this;
|
|
10
11
|
getParent(): undefined;
|
|
11
12
|
getScopes(): never[];
|
|
@@ -16,7 +16,7 @@ export declare class Container implements IContainer {
|
|
|
16
16
|
constructor(injector: IInjector, options?: {
|
|
17
17
|
parent?: IContainer;
|
|
18
18
|
tags?: Tag[];
|
|
19
|
-
onConstruct?: (instance: Instance) => void;
|
|
19
|
+
onConstruct?: (instance: Instance, scope: IContainer) => void;
|
|
20
20
|
onDispose?: (scope: IContainer) => void;
|
|
21
21
|
});
|
|
22
22
|
add(registration: IRegistration): this;
|
|
@@ -26,13 +26,16 @@ export declare class Container implements IContainer {
|
|
|
26
26
|
dispose({ cascade }?: {
|
|
27
27
|
cascade?: boolean;
|
|
28
28
|
}): void;
|
|
29
|
+
detachFromParent(): void;
|
|
29
30
|
use(module: IContainerModule): this;
|
|
30
31
|
hasProvider(key: DependencyKey): boolean;
|
|
31
32
|
resolveManyByAlias(predicate: AliasPredicate, { args, child, lazy }?: ResolveOptions, result?: Map<DependencyKey, unknown>): Map<DependencyKey, unknown>;
|
|
32
33
|
resolveOneByAlias<T>(predicate: AliasPredicate, { args, child, lazy }?: ResolveOptions): [DependencyKey, T];
|
|
33
34
|
getParent(): IContainer;
|
|
34
35
|
getScopes(): IContainer[];
|
|
35
|
-
getInstances(
|
|
36
|
+
getInstances({ cascade }?: {
|
|
37
|
+
cascade?: boolean;
|
|
38
|
+
}): Instance[];
|
|
36
39
|
hasTag(tag: Tag): boolean;
|
|
37
40
|
/**
|
|
38
41
|
* @private
|
|
@@ -3,6 +3,7 @@ import { IProvider } from '../provider/IProvider';
|
|
|
3
3
|
import { IRegistration } from '../registration/IRegistration';
|
|
4
4
|
export declare class EmptyContainer implements IContainer {
|
|
5
5
|
get isDisposed(): boolean;
|
|
6
|
+
detachFromParent(): void;
|
|
6
7
|
hasProvider(key: string): boolean;
|
|
7
8
|
getParent(): undefined;
|
|
8
9
|
getScopes(): never[];
|
|
@@ -43,7 +43,10 @@ export interface IContainer extends Resolvable, Tagged {
|
|
|
43
43
|
hasProvider(key: DependencyKey): boolean;
|
|
44
44
|
getParent(): IContainer | undefined;
|
|
45
45
|
getScopes(): IContainer[];
|
|
46
|
-
getInstances(
|
|
46
|
+
getInstances(options?: {
|
|
47
|
+
cascade?: boolean;
|
|
48
|
+
}): Instance[];
|
|
47
49
|
resolveManyByAlias(predicate: AliasPredicate, options?: ResolveOptions, result?: Map<DependencyKey, unknown>): Map<DependencyKey, unknown>;
|
|
48
50
|
resolveOneByAlias<T>(predicate: AliasPredicate, options?: ResolveOptions): [DependencyKey, T];
|
|
51
|
+
detachFromParent(): void;
|
|
49
52
|
}
|
|
@@ -9,7 +9,6 @@ export interface IHookContext {
|
|
|
9
9
|
args?: unknown[];
|
|
10
10
|
}): unknown;
|
|
11
11
|
setProperty(fn: InjectFn): void;
|
|
12
|
-
getProperty(): unknown;
|
|
13
12
|
}
|
|
14
13
|
export declare class HookContext implements IHookContext {
|
|
15
14
|
instance: object;
|
|
@@ -21,7 +20,6 @@ export declare class HookContext implements IHookContext {
|
|
|
21
20
|
args?: unknown[];
|
|
22
21
|
}): unknown;
|
|
23
22
|
setProperty(fn: InjectFn): void;
|
|
24
|
-
getProperty(): unknown;
|
|
25
23
|
}
|
|
26
24
|
export type CreateHookContext = (Target: object, scope: IContainer, methodName?: string) => IHookContext;
|
|
27
25
|
export declare const createHookContext: CreateHookContext;
|