@vercube/di 0.0.22 → 0.0.24
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 +10 -6
- package/dist/index.mjs +231 -235
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -3,10 +3,10 @@
|
|
|
3
3
|
<br>
|
|
4
4
|
<br>
|
|
5
5
|
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
6
|
+
# Vercube
|
|
7
|
+
|
|
8
|
+
Next generation HTTP framework
|
|
9
|
+
|
|
10
10
|
<a href="https://www.npmjs.com/package/@vercube/cli">
|
|
11
11
|
<img src="https://img.shields.io/npm/v/%40vercube%2Fdi?style=for-the-badge&logo=npm&color=%23767eff" alt="npm"/>
|
|
12
12
|
</a>
|
|
@@ -16,6 +16,9 @@
|
|
|
16
16
|
<a href="https://github.com/vercube/vercube/blob/main/LICENSE" target="_blank">
|
|
17
17
|
<img src="https://img.shields.io/npm/l/%40vercube%2Fdi?style=for-the-badge&color=%23767eff" alt="License"/>
|
|
18
18
|
</a>
|
|
19
|
+
<a href="https://codecov.io/gh/vercube/vercube" target="_blank">
|
|
20
|
+
<img src="https://img.shields.io/codecov/c/github/vercube/vercube?style=for-the-badge&color=%23767eff" alt="Coverage"/>
|
|
21
|
+
</a>
|
|
19
22
|
<br/>
|
|
20
23
|
<br/>
|
|
21
24
|
</div>
|
|
@@ -23,8 +26,9 @@
|
|
|
23
26
|
An ultra-efficient JavaScript server framework that runs anywhere - Node.js, Bun, or Deno - with unmatched flexibility and complete configurability for developers who refuse to sacrifice speed or control.
|
|
24
27
|
|
|
25
28
|
## <a name="module">Dependencie Injection Module</a>
|
|
26
|
-
The Dependency Injection (DI) module provides a powerful and flexible dependency injection system for Vercube applications. It enables loose coupling between components and makes your application more maintainable and testable.
|
|
27
29
|
|
|
30
|
+
The Dependency Injection (DI) module provides a powerful and flexible dependency injection system for Vercube applications. It enables loose coupling between components and makes your application more maintainable and testable.
|
|
28
31
|
|
|
29
32
|
## <a name="documentation">📖 Documentation</a>
|
|
30
|
-
|
|
33
|
+
|
|
34
|
+
Comprehensive documentation is available at [vercube.dev](https://vercube.dev). There you'll find detailed module descriptions, project information, guides, and everything else you need to know about Vercube.
|
package/dist/index.mjs
CHANGED
|
@@ -28,241 +28,6 @@ var BaseDecorator = class {
|
|
|
28
28
|
destroyed() {}
|
|
29
29
|
};
|
|
30
30
|
|
|
31
|
-
//#endregion
|
|
32
|
-
//#region src/Types/IOCTypes.ts
|
|
33
|
-
let IOC;
|
|
34
|
-
(function(_IOC) {
|
|
35
|
-
let ServiceFactoryType = /* @__PURE__ */ function(ServiceFactoryType$1) {
|
|
36
|
-
ServiceFactoryType$1["CLASS"] = "CLASS";
|
|
37
|
-
ServiceFactoryType$1["CLASS_SINGLETON"] = "CLASS_SINGLETON";
|
|
38
|
-
ServiceFactoryType$1["INSTANCE"] = "INSTANCE";
|
|
39
|
-
return ServiceFactoryType$1;
|
|
40
|
-
}({});
|
|
41
|
-
_IOC.ServiceFactoryType = ServiceFactoryType;
|
|
42
|
-
let InjectMethod = /* @__PURE__ */ function(InjectMethod$1) {
|
|
43
|
-
InjectMethod$1["LAZY"] = "LAZY";
|
|
44
|
-
InjectMethod$1["STATIC"] = "STATIC";
|
|
45
|
-
return InjectMethod$1;
|
|
46
|
-
}({});
|
|
47
|
-
_IOC.InjectMethod = InjectMethod;
|
|
48
|
-
let DependencyType = /* @__PURE__ */ function(DependencyType$1) {
|
|
49
|
-
DependencyType$1[DependencyType$1["STANDARD"] = 0] = "STANDARD";
|
|
50
|
-
DependencyType$1[DependencyType$1["OPTIONAL"] = 1] = "OPTIONAL";
|
|
51
|
-
return DependencyType$1;
|
|
52
|
-
}({});
|
|
53
|
-
_IOC.DependencyType = DependencyType;
|
|
54
|
-
})(IOC || (IOC = {}));
|
|
55
|
-
|
|
56
|
-
//#endregion
|
|
57
|
-
//#region src/Domain/Engine.ts
|
|
58
|
-
/**
|
|
59
|
-
* This map holds metadata for ALL classes in system along with their dependencies. Original idea was
|
|
60
|
-
* to store those informations in object prototype, but accessing this map is blazing fast with Map
|
|
61
|
-
* container (<1ms).
|
|
62
|
-
*/
|
|
63
|
-
const classMap = /* @__PURE__ */ new Map();
|
|
64
|
-
const ROOT_PROTO = Object.getPrototypeOf({});
|
|
65
|
-
/**
|
|
66
|
-
* This method registers @Inject() in particular class.
|
|
67
|
-
* @param prototype class prototype for which we register @Inject()
|
|
68
|
-
* @param propertyName name of property that is inejcted
|
|
69
|
-
* @param dependency what we should inject there
|
|
70
|
-
* @param type type of dependency (standard or optional dependency)
|
|
71
|
-
*/
|
|
72
|
-
function registerInject(prototype, propertyName, dependency, type) {
|
|
73
|
-
let entry = classMap.get(prototype);
|
|
74
|
-
if (!entry) {
|
|
75
|
-
const newEntry = { deps: [] };
|
|
76
|
-
entry = newEntry;
|
|
77
|
-
classMap.set(prototype, entry);
|
|
78
|
-
}
|
|
79
|
-
const newDep = {
|
|
80
|
-
propertyName,
|
|
81
|
-
dependency,
|
|
82
|
-
type
|
|
83
|
-
};
|
|
84
|
-
entry.deps.push(newDep);
|
|
85
|
-
}
|
|
86
|
-
/**
|
|
87
|
-
* Returns classmap entry for particular class. It holds information about @Injects for this particular class.
|
|
88
|
-
* @param classType type of class to check
|
|
89
|
-
* @returns class map entry or null if cannot be found
|
|
90
|
-
*/
|
|
91
|
-
function getEntryForClass(classType) {
|
|
92
|
-
const entry = classMap.get(classType.prototype);
|
|
93
|
-
return entry === void 0 ? null : entry;
|
|
94
|
-
}
|
|
95
|
-
/**
|
|
96
|
-
* Returns array of dependencies for particular class instance.
|
|
97
|
-
* @param instance class instance
|
|
98
|
-
* @returns array of @Inject dependencies defined for this class
|
|
99
|
-
*/
|
|
100
|
-
function getDeps(instance) {
|
|
101
|
-
const prototype = Object.getPrototypeOf(instance);
|
|
102
|
-
if (!prototype) return [];
|
|
103
|
-
const entry = classMap.get(prototype);
|
|
104
|
-
return entry !== void 0 && entry.deps !== void 0 ? entry.deps : [];
|
|
105
|
-
}
|
|
106
|
-
/**
|
|
107
|
-
* This method injects stuff into class, using container passed as first argument. We need container as
|
|
108
|
-
* inject execution is always context based.
|
|
109
|
-
* @param container container instance that is providing dependencies
|
|
110
|
-
* @param instance class instance to inject
|
|
111
|
-
* @param method inject method, "lazy" queries dep during property access while "static" injects during class creation
|
|
112
|
-
*/
|
|
113
|
-
function injectDeps(container, instance, method) {
|
|
114
|
-
let prototype = Object.getPrototypeOf(instance);
|
|
115
|
-
if (!prototype) return;
|
|
116
|
-
/**
|
|
117
|
-
* Here we will traverse through prototype chain until we hit dead end (ROOT_PROTO). This is because we
|
|
118
|
-
* must process inject for current class and also for every base class.
|
|
119
|
-
*
|
|
120
|
-
* So we will use "do" loop to iterate full prototype chain.
|
|
121
|
-
*/
|
|
122
|
-
do {
|
|
123
|
-
const entry = classMap.get(prototype);
|
|
124
|
-
if (entry) for (const iter of entry.deps) {
|
|
125
|
-
const propertyName = iter.propertyName;
|
|
126
|
-
const dependency = iter.dependency;
|
|
127
|
-
const type = iter.type;
|
|
128
|
-
if (Object.prototype.hasOwnProperty.call(instance, propertyName) && instance[propertyName] !== void 0) continue;
|
|
129
|
-
if (type === IOC.DependencyType.OPTIONAL) {
|
|
130
|
-
Object.defineProperty(instance, propertyName, { get: function() {
|
|
131
|
-
return container.getOptional(dependency);
|
|
132
|
-
} });
|
|
133
|
-
continue;
|
|
134
|
-
}
|
|
135
|
-
switch (method) {
|
|
136
|
-
case IOC.InjectMethod.LAZY:
|
|
137
|
-
Object.defineProperty(instance, propertyName, { get: function() {
|
|
138
|
-
return container.get(dependency);
|
|
139
|
-
} });
|
|
140
|
-
break;
|
|
141
|
-
case IOC.InjectMethod.STATIC:
|
|
142
|
-
instance[propertyName] = container.get(dependency);
|
|
143
|
-
break;
|
|
144
|
-
default: throw new Error(`IOCEngine.injectDeps() - invalid inject method ${method}`);
|
|
145
|
-
}
|
|
146
|
-
}
|
|
147
|
-
prototype = Object.getPrototypeOf(prototype);
|
|
148
|
-
} while (prototype && prototype !== ROOT_PROTO);
|
|
149
|
-
}
|
|
150
|
-
const IOCEngine = {
|
|
151
|
-
registerInject,
|
|
152
|
-
getEntryForClass,
|
|
153
|
-
injectDeps,
|
|
154
|
-
getDeps
|
|
155
|
-
};
|
|
156
|
-
|
|
157
|
-
//#endregion
|
|
158
|
-
//#region src/Decorators/Inject.ts
|
|
159
|
-
/**
|
|
160
|
-
* Injects a dependency with particular key to service.
|
|
161
|
-
* @param key key to inject
|
|
162
|
-
* @returns decorator
|
|
163
|
-
*/
|
|
164
|
-
function Inject(key) {
|
|
165
|
-
return (target, propertyName) => {
|
|
166
|
-
IOCEngine.registerInject(target, propertyName, key, IOC.DependencyType.STANDARD);
|
|
167
|
-
};
|
|
168
|
-
}
|
|
169
|
-
|
|
170
|
-
//#endregion
|
|
171
|
-
//#region src/Decorators/InjectOptional.ts
|
|
172
|
-
/**
|
|
173
|
-
* Injects a dependency with particular key to service.
|
|
174
|
-
* @param key key to inject
|
|
175
|
-
* @returns decorator
|
|
176
|
-
*/
|
|
177
|
-
function InjectOptional(key) {
|
|
178
|
-
return (target, propertyName) => {
|
|
179
|
-
IOCEngine.registerInject(target, propertyName, key, IOC.DependencyType.OPTIONAL);
|
|
180
|
-
};
|
|
181
|
-
}
|
|
182
|
-
|
|
183
|
-
//#endregion
|
|
184
|
-
//#region src/Decorators/Init.ts
|
|
185
|
-
/**
|
|
186
|
-
* This decorator fires the decorated function as soon as decorators are injected. You
|
|
187
|
-
* can use this for initialization logic in runtime-loaded container deps.
|
|
188
|
-
*/
|
|
189
|
-
var InitDecorator = class extends BaseDecorator {
|
|
190
|
-
/**
|
|
191
|
-
* Called when decorator is initialized.
|
|
192
|
-
*/
|
|
193
|
-
created() {
|
|
194
|
-
if (typeof this.instance[this.propertyName] === "function") this.instance[this.propertyName]();
|
|
195
|
-
}
|
|
196
|
-
};
|
|
197
|
-
/**
|
|
198
|
-
* Decorator that automatically executes the decorated method when dependencies are injected.
|
|
199
|
-
* Use this decorator to run initialization logic for runtime-loaded container dependencies.
|
|
200
|
-
* @returns {Function} Decorator function that creates an InitDecorator instance
|
|
201
|
-
*/
|
|
202
|
-
function Init() {
|
|
203
|
-
return createDecorator(InitDecorator, {});
|
|
204
|
-
}
|
|
205
|
-
|
|
206
|
-
//#endregion
|
|
207
|
-
//#region src/Decorators/Destroy.ts
|
|
208
|
-
/**
|
|
209
|
-
* Decorator that handles cleanup tasks when a service or component is destroyed.
|
|
210
|
-
* This decorator class extends BaseDecorator and executes the decorated method
|
|
211
|
-
* during the destruction phase.
|
|
212
|
-
*/
|
|
213
|
-
var DestroyDecorator = class extends BaseDecorator {
|
|
214
|
-
/**
|
|
215
|
-
* Called when decorator is destroyed. Executes the decorated method if it exists
|
|
216
|
-
* as a function on the instance. Used for cleanup tasks like unregistering
|
|
217
|
-
* listeners or clearing timers.
|
|
218
|
-
*/
|
|
219
|
-
destroyed() {
|
|
220
|
-
if (typeof this.instance[this.propertyName] === "function") this.instance[this.propertyName]();
|
|
221
|
-
}
|
|
222
|
-
};
|
|
223
|
-
/**
|
|
224
|
-
* Decorator that automatically executes the decorated method when the service or component
|
|
225
|
-
* is destroyed. Use this decorator to run cleanup logic like unregistering event listeners
|
|
226
|
-
* or clearing timers.
|
|
227
|
-
*
|
|
228
|
-
* @example
|
|
229
|
-
* ```typescript
|
|
230
|
-
* class MyService {
|
|
231
|
-
* @Destroy()
|
|
232
|
-
* cleanup() {
|
|
233
|
-
* // Cleanup logic here
|
|
234
|
-
* }
|
|
235
|
-
* }
|
|
236
|
-
* ```
|
|
237
|
-
* @returns {Function} Decorator function that creates a DestroyDecorator instance
|
|
238
|
-
*/
|
|
239
|
-
function Destroy() {
|
|
240
|
-
return createDecorator(DestroyDecorator, {});
|
|
241
|
-
}
|
|
242
|
-
|
|
243
|
-
//#endregion
|
|
244
|
-
//#region src/Domain/ContainerEvents.ts
|
|
245
|
-
/**
|
|
246
|
-
* This class allows for container to listen on various IOC events.
|
|
247
|
-
*/
|
|
248
|
-
var ContainerEvents = class {
|
|
249
|
-
fOnExpanded = [];
|
|
250
|
-
/**
|
|
251
|
-
* Registers to container "onExpanded" event.
|
|
252
|
-
* @param handler event handler
|
|
253
|
-
*/
|
|
254
|
-
onExpanded(handler) {
|
|
255
|
-
this.fOnExpanded.push(handler);
|
|
256
|
-
}
|
|
257
|
-
/**
|
|
258
|
-
* Calls on expanded event.
|
|
259
|
-
* @param serviceKeys key of service we have installed
|
|
260
|
-
*/
|
|
261
|
-
callOnExpanded(serviceKeys) {
|
|
262
|
-
for (const handler of this.fOnExpanded) handler(serviceKeys);
|
|
263
|
-
}
|
|
264
|
-
};
|
|
265
|
-
|
|
266
31
|
//#endregion
|
|
267
32
|
//#region src/Utils/Utils.ts
|
|
268
33
|
/**
|
|
@@ -366,6 +131,29 @@ function destroyContainer(container) {
|
|
|
366
131
|
containerMap.delete(container);
|
|
367
132
|
}
|
|
368
133
|
|
|
134
|
+
//#endregion
|
|
135
|
+
//#region src/Domain/ContainerEvents.ts
|
|
136
|
+
/**
|
|
137
|
+
* This class allows for container to listen on various IOC events.
|
|
138
|
+
*/
|
|
139
|
+
var ContainerEvents = class {
|
|
140
|
+
fOnExpanded = [];
|
|
141
|
+
/**
|
|
142
|
+
* Registers to container "onExpanded" event.
|
|
143
|
+
* @param handler event handler
|
|
144
|
+
*/
|
|
145
|
+
onExpanded(handler) {
|
|
146
|
+
this.fOnExpanded.push(handler);
|
|
147
|
+
}
|
|
148
|
+
/**
|
|
149
|
+
* Calls on expanded event.
|
|
150
|
+
* @param serviceKeys key of service we have installed
|
|
151
|
+
*/
|
|
152
|
+
callOnExpanded(serviceKeys) {
|
|
153
|
+
for (const handler of this.fOnExpanded) handler(serviceKeys);
|
|
154
|
+
}
|
|
155
|
+
};
|
|
156
|
+
|
|
369
157
|
//#endregion
|
|
370
158
|
//#region src/Domain/Container.ts
|
|
371
159
|
/**
|
|
@@ -684,5 +472,213 @@ var Container = class Container {
|
|
|
684
472
|
}
|
|
685
473
|
};
|
|
686
474
|
|
|
475
|
+
//#endregion
|
|
476
|
+
//#region src/Types/IOCTypes.ts
|
|
477
|
+
let IOC;
|
|
478
|
+
(function(_IOC) {
|
|
479
|
+
_IOC.ServiceFactoryType = /* @__PURE__ */ function(ServiceFactoryType) {
|
|
480
|
+
ServiceFactoryType["CLASS"] = "CLASS";
|
|
481
|
+
ServiceFactoryType["CLASS_SINGLETON"] = "CLASS_SINGLETON";
|
|
482
|
+
ServiceFactoryType["INSTANCE"] = "INSTANCE";
|
|
483
|
+
return ServiceFactoryType;
|
|
484
|
+
}({});
|
|
485
|
+
_IOC.InjectMethod = /* @__PURE__ */ function(InjectMethod) {
|
|
486
|
+
InjectMethod["LAZY"] = "LAZY";
|
|
487
|
+
InjectMethod["STATIC"] = "STATIC";
|
|
488
|
+
return InjectMethod;
|
|
489
|
+
}({});
|
|
490
|
+
_IOC.DependencyType = /* @__PURE__ */ function(DependencyType) {
|
|
491
|
+
DependencyType[DependencyType["STANDARD"] = 0] = "STANDARD";
|
|
492
|
+
DependencyType[DependencyType["OPTIONAL"] = 1] = "OPTIONAL";
|
|
493
|
+
return DependencyType;
|
|
494
|
+
}({});
|
|
495
|
+
})(IOC || (IOC = {}));
|
|
496
|
+
|
|
497
|
+
//#endregion
|
|
498
|
+
//#region src/Domain/Engine.ts
|
|
499
|
+
/**
|
|
500
|
+
* This map holds metadata for ALL classes in system along with their dependencies. Original idea was
|
|
501
|
+
* to store those informations in object prototype, but accessing this map is blazing fast with Map
|
|
502
|
+
* container (<1ms).
|
|
503
|
+
*/
|
|
504
|
+
const classMap = /* @__PURE__ */ new Map();
|
|
505
|
+
const ROOT_PROTO = Object.getPrototypeOf({});
|
|
506
|
+
/**
|
|
507
|
+
* This method registers @Inject() in particular class.
|
|
508
|
+
* @param prototype class prototype for which we register @Inject()
|
|
509
|
+
* @param propertyName name of property that is inejcted
|
|
510
|
+
* @param dependency what we should inject there
|
|
511
|
+
* @param type type of dependency (standard or optional dependency)
|
|
512
|
+
*/
|
|
513
|
+
function registerInject(prototype, propertyName, dependency, type) {
|
|
514
|
+
let entry = classMap.get(prototype);
|
|
515
|
+
if (!entry) {
|
|
516
|
+
entry = { deps: [] };
|
|
517
|
+
classMap.set(prototype, entry);
|
|
518
|
+
}
|
|
519
|
+
const newDep = {
|
|
520
|
+
propertyName,
|
|
521
|
+
dependency,
|
|
522
|
+
type
|
|
523
|
+
};
|
|
524
|
+
entry.deps.push(newDep);
|
|
525
|
+
}
|
|
526
|
+
/**
|
|
527
|
+
* Returns classmap entry for particular class. It holds information about @Injects for this particular class.
|
|
528
|
+
* @param classType type of class to check
|
|
529
|
+
* @returns class map entry or null if cannot be found
|
|
530
|
+
*/
|
|
531
|
+
function getEntryForClass(classType) {
|
|
532
|
+
const entry = classMap.get(classType.prototype);
|
|
533
|
+
return entry === void 0 ? null : entry;
|
|
534
|
+
}
|
|
535
|
+
/**
|
|
536
|
+
* Returns array of dependencies for particular class instance.
|
|
537
|
+
* @param instance class instance
|
|
538
|
+
* @returns array of @Inject dependencies defined for this class
|
|
539
|
+
*/
|
|
540
|
+
function getDeps(instance) {
|
|
541
|
+
const prototype = Object.getPrototypeOf(instance);
|
|
542
|
+
if (!prototype) return [];
|
|
543
|
+
const entry = classMap.get(prototype);
|
|
544
|
+
return entry !== void 0 && entry.deps !== void 0 ? entry.deps : [];
|
|
545
|
+
}
|
|
546
|
+
/**
|
|
547
|
+
* This method injects stuff into class, using container passed as first argument. We need container as
|
|
548
|
+
* inject execution is always context based.
|
|
549
|
+
* @param container container instance that is providing dependencies
|
|
550
|
+
* @param instance class instance to inject
|
|
551
|
+
* @param method inject method, "lazy" queries dep during property access while "static" injects during class creation
|
|
552
|
+
*/
|
|
553
|
+
function injectDeps(container, instance, method) {
|
|
554
|
+
let prototype = Object.getPrototypeOf(instance);
|
|
555
|
+
if (!prototype) return;
|
|
556
|
+
/**
|
|
557
|
+
* Here we will traverse through prototype chain until we hit dead end (ROOT_PROTO). This is because we
|
|
558
|
+
* must process inject for current class and also for every base class.
|
|
559
|
+
*
|
|
560
|
+
* So we will use "do" loop to iterate full prototype chain.
|
|
561
|
+
*/
|
|
562
|
+
do {
|
|
563
|
+
const entry = classMap.get(prototype);
|
|
564
|
+
if (entry) for (const iter of entry.deps) {
|
|
565
|
+
const propertyName = iter.propertyName;
|
|
566
|
+
const dependency = iter.dependency;
|
|
567
|
+
const type = iter.type;
|
|
568
|
+
if (Object.prototype.hasOwnProperty.call(instance, propertyName) && instance[propertyName] !== void 0) continue;
|
|
569
|
+
if (type === IOC.DependencyType.OPTIONAL) {
|
|
570
|
+
Object.defineProperty(instance, propertyName, { get: function() {
|
|
571
|
+
return container.getOptional(dependency);
|
|
572
|
+
} });
|
|
573
|
+
continue;
|
|
574
|
+
}
|
|
575
|
+
switch (method) {
|
|
576
|
+
case IOC.InjectMethod.LAZY:
|
|
577
|
+
Object.defineProperty(instance, propertyName, { get: function() {
|
|
578
|
+
return container.get(dependency);
|
|
579
|
+
} });
|
|
580
|
+
break;
|
|
581
|
+
case IOC.InjectMethod.STATIC:
|
|
582
|
+
instance[propertyName] = container.get(dependency);
|
|
583
|
+
break;
|
|
584
|
+
default: throw new Error(`IOCEngine.injectDeps() - invalid inject method ${method}`);
|
|
585
|
+
}
|
|
586
|
+
}
|
|
587
|
+
prototype = Object.getPrototypeOf(prototype);
|
|
588
|
+
} while (prototype && prototype !== ROOT_PROTO);
|
|
589
|
+
}
|
|
590
|
+
const IOCEngine = {
|
|
591
|
+
registerInject,
|
|
592
|
+
getEntryForClass,
|
|
593
|
+
injectDeps,
|
|
594
|
+
getDeps
|
|
595
|
+
};
|
|
596
|
+
|
|
597
|
+
//#endregion
|
|
598
|
+
//#region src/Decorators/Inject.ts
|
|
599
|
+
/**
|
|
600
|
+
* Injects a dependency with particular key to service.
|
|
601
|
+
* @param key key to inject
|
|
602
|
+
* @returns decorator
|
|
603
|
+
*/
|
|
604
|
+
function Inject(key) {
|
|
605
|
+
return (target, propertyName) => {
|
|
606
|
+
IOCEngine.registerInject(target, propertyName, key, IOC.DependencyType.STANDARD);
|
|
607
|
+
};
|
|
608
|
+
}
|
|
609
|
+
|
|
610
|
+
//#endregion
|
|
611
|
+
//#region src/Decorators/InjectOptional.ts
|
|
612
|
+
/**
|
|
613
|
+
* Injects a dependency with particular key to service.
|
|
614
|
+
* @param key key to inject
|
|
615
|
+
* @returns decorator
|
|
616
|
+
*/
|
|
617
|
+
function InjectOptional(key) {
|
|
618
|
+
return (target, propertyName) => {
|
|
619
|
+
IOCEngine.registerInject(target, propertyName, key, IOC.DependencyType.OPTIONAL);
|
|
620
|
+
};
|
|
621
|
+
}
|
|
622
|
+
|
|
623
|
+
//#endregion
|
|
624
|
+
//#region src/Decorators/Init.ts
|
|
625
|
+
/**
|
|
626
|
+
* This decorator fires the decorated function as soon as decorators are injected. You
|
|
627
|
+
* can use this for initialization logic in runtime-loaded container deps.
|
|
628
|
+
*/
|
|
629
|
+
var InitDecorator = class extends BaseDecorator {
|
|
630
|
+
/**
|
|
631
|
+
* Called when decorator is initialized.
|
|
632
|
+
*/
|
|
633
|
+
created() {
|
|
634
|
+
if (typeof this.instance[this.propertyName] === "function") this.instance[this.propertyName]();
|
|
635
|
+
}
|
|
636
|
+
};
|
|
637
|
+
/**
|
|
638
|
+
* Decorator that automatically executes the decorated method when dependencies are injected.
|
|
639
|
+
* Use this decorator to run initialization logic for runtime-loaded container dependencies.
|
|
640
|
+
* @returns {Function} Decorator function that creates an InitDecorator instance
|
|
641
|
+
*/
|
|
642
|
+
function Init() {
|
|
643
|
+
return createDecorator(InitDecorator, {});
|
|
644
|
+
}
|
|
645
|
+
|
|
646
|
+
//#endregion
|
|
647
|
+
//#region src/Decorators/Destroy.ts
|
|
648
|
+
/**
|
|
649
|
+
* Decorator that handles cleanup tasks when a service or component is destroyed.
|
|
650
|
+
* This decorator class extends BaseDecorator and executes the decorated method
|
|
651
|
+
* during the destruction phase.
|
|
652
|
+
*/
|
|
653
|
+
var DestroyDecorator = class extends BaseDecorator {
|
|
654
|
+
/**
|
|
655
|
+
* Called when decorator is destroyed. Executes the decorated method if it exists
|
|
656
|
+
* as a function on the instance. Used for cleanup tasks like unregistering
|
|
657
|
+
* listeners or clearing timers.
|
|
658
|
+
*/
|
|
659
|
+
destroyed() {
|
|
660
|
+
if (typeof this.instance[this.propertyName] === "function") this.instance[this.propertyName]();
|
|
661
|
+
}
|
|
662
|
+
};
|
|
663
|
+
/**
|
|
664
|
+
* Decorator that automatically executes the decorated method when the service or component
|
|
665
|
+
* is destroyed. Use this decorator to run cleanup logic like unregistering event listeners
|
|
666
|
+
* or clearing timers.
|
|
667
|
+
*
|
|
668
|
+
* @example
|
|
669
|
+
* ```typescript
|
|
670
|
+
* class MyService {
|
|
671
|
+
* @Destroy()
|
|
672
|
+
* cleanup() {
|
|
673
|
+
* // Cleanup logic here
|
|
674
|
+
* }
|
|
675
|
+
* }
|
|
676
|
+
* ```
|
|
677
|
+
* @returns {Function} Decorator function that creates a DestroyDecorator instance
|
|
678
|
+
*/
|
|
679
|
+
function Destroy() {
|
|
680
|
+
return createDecorator(DestroyDecorator, {});
|
|
681
|
+
}
|
|
682
|
+
|
|
687
683
|
//#endregion
|
|
688
684
|
export { BaseDecorator, Container, Destroy, IOC, Identity, Init, Inject, InjectOptional, createDecorator, destroyContainer, destroyDecorators, initializeContainer, initializeDecorators };
|