@spinajs/di 2.0.385 → 2.0.387

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.
@@ -1,9 +1,11 @@
1
1
  import { TypedArray } from './array.js';
2
- import { IContainer } from './interfaces.js';
2
+ import { IContainer, IInjectDescriptor } from './interfaces.js';
3
3
  import { Class } from './types.js';
4
4
  export declare class ContainerCache {
5
5
  private container;
6
6
  private cache;
7
+ private resolutionPromises;
8
+ private creatingKeys;
7
9
  constructor(container: IContainer);
8
10
  [Symbol.iterator](): Generator<{
9
11
  key: string;
@@ -11,8 +13,25 @@ export declare class ContainerCache {
11
13
  }, void, unknown>;
12
14
  remove(key: string | Class<any> | TypedArray<any>, parent?: boolean): void;
13
15
  add(key: string | Class<any> | object, instance: any): void;
16
+ /**
17
+ * Add instance to cache only if it doesn't already exist (atomic operation for singletons)
18
+ */
19
+ addIfNotExists(key: string | Class<any> | object, instance: any): boolean;
14
20
  has(key: string | Class<any> | object | TypedArray<any>, parent?: boolean): boolean;
15
21
  get(key: string | Class<any> | TypedArray<any>, parent?: boolean): any;
22
+ /**
23
+ * Atomic get-or-create operation for singleton services
24
+ * Prevents concurrent creation of the same singleton instance
25
+ */
26
+ getOrCreate<T>(sourceType: string | Class<any> | TypedArray<any> | object, targetType: string | Class<any> | TypedArray<any>, factory: () => Promise<T> | T, isSingleton: boolean, descriptor: IInjectDescriptor<unknown>, options?: unknown[]): Promise<T> | T;
27
+ /**
28
+ * Get resolution statistics for monitoring
29
+ */
30
+ getResolutionStats(): {
31
+ cacheSize: number;
32
+ activeResolutions: number;
33
+ resolutionKeys: string[];
34
+ };
16
35
  clear(): void;
17
36
  }
18
37
  //# sourceMappingURL=container-cache.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"container-cache.d.ts","sourceRoot":"","sources":["../../src/container-cache.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,UAAU,EAAE,MAAM,YAAY,CAAC;AAExC,OAAO,EAAE,UAAU,EAAE,MAAM,iBAAiB,CAAC;AAC7C,OAAO,EAAE,KAAK,EAAE,MAAM,YAAY,CAAC;AAEnC,qBAAa,cAAc;IAGb,OAAO,CAAC,SAAS;IAF7B,OAAO,CAAC,KAAK,CAAqB;gBAEd,SAAS,EAAE,UAAU;IAQxC,CAAC,MAAM,CAAC,QAAQ,CAAC;;;;IAQX,MAAM,CAAC,GAAG,EAAE,MAAM,GAAG,KAAK,CAAC,GAAG,CAAC,GAAG,UAAU,CAAC,GAAG,CAAC,EAAE,MAAM,CAAC,EAAE,OAAO,GAAG,IAAI;IAQ1E,GAAG,CAAC,GAAG,EAAE,MAAM,GAAG,KAAK,CAAC,GAAG,CAAC,GAAG,MAAM,EAAE,QAAQ,EAAE,GAAG;IAYpD,GAAG,CAAC,GAAG,EAAE,MAAM,GAAG,KAAK,CAAC,GAAG,CAAC,GAAG,MAAM,GAAG,UAAU,CAAC,GAAG,CAAC,EAAE,MAAM,CAAC,EAAE,OAAO,GAAG,OAAO;IAYnF,GAAG,CAAC,GAAG,EAAE,MAAM,GAAG,KAAK,CAAC,GAAG,CAAC,GAAG,UAAU,CAAC,GAAG,CAAC,EAAE,MAAM,CAAC,EAAE,OAAO,GAAG,GAAG;IActE,KAAK;CAIb"}
1
+ {"version":3,"file":"container-cache.d.ts","sourceRoot":"","sources":["../../src/container-cache.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,UAAU,EAAE,MAAM,YAAY,CAAC;AAExC,OAAO,EAAE,UAAU,EAAE,iBAAiB,EAAkB,MAAM,iBAAiB,CAAC;AAChF,OAAO,EAAE,KAAK,EAAE,MAAM,YAAY,CAAC;AAInC,qBAAa,cAAc;IAOb,OAAO,CAAC,SAAS;IAN7B,OAAO,CAAC,KAAK,CAAqB;IAElC,OAAO,CAAC,kBAAkB,CAAwC;IAElE,OAAO,CAAC,YAAY,CAA0B;gBAE1B,SAAS,EAAE,UAAU;IAQxC,CAAC,MAAM,CAAC,QAAQ,CAAC;;;;IAQX,MAAM,CAAC,GAAG,EAAE,MAAM,GAAG,KAAK,CAAC,GAAG,CAAC,GAAG,UAAU,CAAC,GAAG,CAAC,EAAE,MAAM,CAAC,EAAE,OAAO,GAAG,IAAI;IAQ1E,GAAG,CAAC,GAAG,EAAE,MAAM,GAAG,KAAK,CAAC,GAAG,CAAC,GAAG,MAAM,EAAE,QAAQ,EAAE,GAAG;IAY3D;;OAEG;IACI,cAAc,CAAC,GAAG,EAAE,MAAM,GAAG,KAAK,CAAC,GAAG,CAAC,GAAG,MAAM,EAAE,QAAQ,EAAE,GAAG,GAAG,OAAO;IAWzE,GAAG,CAAC,GAAG,EAAE,MAAM,GAAG,KAAK,CAAC,GAAG,CAAC,GAAG,MAAM,GAAG,UAAU,CAAC,GAAG,CAAC,EAAE,MAAM,CAAC,EAAE,OAAO,GAAG,OAAO;IAanF,GAAG,CAAC,GAAG,EAAE,MAAM,GAAG,KAAK,CAAC,GAAG,CAAC,GAAG,UAAU,CAAC,GAAG,CAAC,EAAE,MAAM,CAAC,EAAE,OAAO,GAAG,GAAG;IAc7E;;;OAGG;IACI,WAAW,CAAC,CAAC,EAClB,UAAU,EAAE,MAAM,GAAG,KAAK,CAAC,GAAG,CAAC,GAAG,UAAU,CAAC,GAAG,CAAC,GAAG,MAAM,EAC1D,UAAU,EAAE,MAAM,GAAG,KAAK,CAAC,GAAG,CAAC,GAAG,UAAU,CAAC,GAAG,CAAC,EACjD,OAAO,EAAE,MAAM,OAAO,CAAC,CAAC,CAAC,GAAG,CAAC,EAC7B,WAAW,EAAE,OAAc,EAC3B,UAAU,EAAE,iBAAiB,CAAC,OAAO,CAAC,EACtC,OAAO,CAAC,EAAE,OAAO,EAAE,GAClB,OAAO,CAAC,CAAC,CAAC,GAAG,CAAC;IA8GjB;;OAEG;IACI,kBAAkB;;;;;IAQlB,KAAK;CAMb"}
@@ -1,7 +1,14 @@
1
+ import { TypedArray } from './array.js';
1
2
  import { getTypeName } from './helpers.js';
3
+ import { ResolveType } from './enums.js';
4
+ import { ResolveException } from './exceptions.js';
2
5
  export class ContainerCache {
3
6
  constructor(container) {
4
7
  this.container = container;
8
+ // Track ongoing resolution promises to prevent concurrent singleton creation
9
+ this.resolutionPromises = new Map();
10
+ // Track keys currently being created synchronously
11
+ this.creatingKeys = new Set();
5
12
  this.cache = new Map();
6
13
  // add to cache container
7
14
  // so we can inject container if needed
@@ -33,6 +40,19 @@ export class ContainerCache {
33
40
  this.cache.set(tName, [instance]);
34
41
  }
35
42
  }
43
+ /**
44
+ * Add instance to cache only if it doesn't already exist (atomic operation for singletons)
45
+ */
46
+ addIfNotExists(key, instance) {
47
+ const tName = getTypeName(key);
48
+ if (this.has(key)) {
49
+ return false; // Already exists, don't add
50
+ }
51
+ else {
52
+ this.cache.set(tName, [instance]);
53
+ return true; // Successfully added
54
+ }
55
+ }
36
56
  has(key, parent) {
37
57
  if (this.cache.has(getTypeName(key))) {
38
58
  return true;
@@ -52,8 +72,123 @@ export class ContainerCache {
52
72
  }
53
73
  return [];
54
74
  }
75
+ /**
76
+ * Atomic get-or-create operation for singleton services
77
+ * Prevents concurrent creation of the same singleton instance
78
+ */
79
+ getOrCreate(sourceType, targetType, factory, isSingleton = true, descriptor, options) {
80
+ const keyName = getTypeName(targetType);
81
+ const sourceTypeKey = getTypeName(sourceType);
82
+ // Fast path: return cached instance if it exists
83
+ if (this.has(targetType, descriptor.resolver === ResolveType.PerChildContainer ? false : true)) {
84
+ const cached = this.get(targetType, descriptor.resolver === ResolveType.PerChildContainer ? false : true);
85
+ if (descriptor.resolver === ResolveType.PerInstanceCheck) {
86
+ if (cached) {
87
+ const found = cached.find((x) => {
88
+ if (!x.__checkInstance__) {
89
+ // eslint-disable-next-line @typescript-eslint/restrict-template-expressions
90
+ throw new ResolveException(`service ${x.constructor.name} is marked as PerInstanceCheck resolver, but no __checkInstance__ function is provided`);
91
+ }
92
+ return x.__checkInstance__(options);
93
+ });
94
+ if (found) {
95
+ return found;
96
+ }
97
+ else {
98
+ return factory();
99
+ }
100
+ }
101
+ }
102
+ return Array.isArray(cached) ? cached[0] : cached;
103
+ }
104
+ // For non-singletons, always create new instance
105
+ if (!isSingleton) {
106
+ return factory();
107
+ }
108
+ // Check if creation is already in progress (async)
109
+ if (this.resolutionPromises.has(keyName)) {
110
+ return this.resolutionPromises.get(keyName);
111
+ }
112
+ // Check if creation is already in progress (sync)
113
+ if (this.creatingKeys.has(keyName)) {
114
+ // This indicates a potential circular dependency or re-entrant call
115
+ if (this.has(targetType)) {
116
+ const cached = this.get(targetType);
117
+ return Array.isArray(cached) ? cached[0] : cached;
118
+ }
119
+ throw new Error(`Circular dependency detected for ${keyName}`);
120
+ }
121
+ // Mark this key as being created to prevent re-entrance
122
+ this.creatingKeys.add(keyName);
123
+ let instance;
124
+ try {
125
+ instance = factory();
126
+ }
127
+ catch (error) {
128
+ this.creatingKeys.delete(keyName);
129
+ throw error;
130
+ }
131
+ const _checkCache = (resolvedInstance) => {
132
+ if (sourceType instanceof TypedArray) {
133
+ // If sourceType is a TypedArray, we need to ensure we cache it correctly
134
+ if (!this.has(sourceTypeKey)) {
135
+ this.add(sourceTypeKey, resolvedInstance);
136
+ }
137
+ else {
138
+ // If it already exists, we should merge the new instance into the existing array
139
+ const existingInstances = this.get(sourceTypeKey);
140
+ if (!existingInstances.includes(resolvedInstance)) {
141
+ existingInstances.push(resolvedInstance);
142
+ }
143
+ }
144
+ const cached = this.get(sourceTypeKey);
145
+ return sourceType instanceof TypedArray ? cached : cached[0];
146
+ }
147
+ else {
148
+ // Cache the instance if not already cached
149
+ if (!this.has(targetType)) {
150
+ this.add(targetType, resolvedInstance);
151
+ }
152
+ }
153
+ // Return the cached version
154
+ const cached = this.get(targetType);
155
+ return cached[0];
156
+ };
157
+ // If factory returns a Promise, handle async resolution
158
+ if (instance instanceof Promise) {
159
+ const creation = instance.then(resolvedInstance => {
160
+ this.creatingKeys.delete(keyName);
161
+ this.resolutionPromises.delete(keyName);
162
+ return _checkCache(resolvedInstance);
163
+ }).catch(error => {
164
+ this.creatingKeys.delete(keyName);
165
+ this.resolutionPromises.delete(keyName);
166
+ throw error;
167
+ });
168
+ // Store the promise to prevent concurrent resolutions
169
+ this.resolutionPromises.set(keyName, creation);
170
+ return creation;
171
+ }
172
+ else {
173
+ // Synchronous resolution
174
+ this.creatingKeys.delete(keyName);
175
+ return _checkCache(instance);
176
+ }
177
+ }
178
+ /**
179
+ * Get resolution statistics for monitoring
180
+ */
181
+ getResolutionStats() {
182
+ return {
183
+ cacheSize: this.cache.size,
184
+ activeResolutions: this.resolutionPromises.size,
185
+ resolutionKeys: Array.from(this.resolutionPromises.keys()),
186
+ };
187
+ }
55
188
  clear() {
56
189
  this.cache.clear();
190
+ this.resolutionPromises.clear();
191
+ this.creatingKeys.clear();
57
192
  this.add(this.container, this.container);
58
193
  }
59
194
  }
@@ -1 +1 @@
1
- {"version":3,"file":"container-cache.js","sourceRoot":"","sources":["../../src/container-cache.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"container-cache.js","sourceRoot":"","sources":["../../src/container-cache.ts"],"names":[],"mappings":"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"}
@@ -23,6 +23,10 @@ export declare class Container extends EventEmitter implements IContainer {
23
23
  * Parent container if avaible
24
24
  */
25
25
  private parent;
26
+ /**
27
+ * Child containers created from this container
28
+ */
29
+ private children;
26
30
  /**
27
31
  * Returns container cache - map object with resolved classes as singletons
28
32
  */
@@ -43,6 +47,14 @@ export declare class Container extends EventEmitter implements IContainer {
43
47
  * Clears container resolved types
44
48
  */
45
49
  clearRegistry(): void;
50
+ /**
51
+ * Get cache statistics for memory monitoring
52
+ */
53
+ getCacheStats(): {
54
+ size: number;
55
+ entries: string[];
56
+ childrenCount: number;
57
+ };
46
58
  /**
47
59
  * Register class/interface to DI.
48
60
  * @param type - interface object to register
@@ -109,6 +121,7 @@ export declare class Container extends EventEmitter implements IContainer {
109
121
  resolve<T>(type: TypedArray<T>, options?: unknown[], check?: boolean): T extends AsyncService ? Promise<T[]> : T[];
110
122
  resolve<T>(type: TypedArray<T>, check?: boolean): T extends AsyncService ? Promise<T[]> : T[];
111
123
  getRegisteredTypes<T>(service: string | Class<T> | TypedArray<T>, parent?: boolean): (Class<unknown> | Factory<unknown>)[];
124
+ private getCurrentType;
112
125
  private resolveType;
113
126
  protected getNewInstance(typeToCreate: Class<unknown> | Factory<unknown>, a?: IResolvedInjection[], options?: unknown[]): Promise<unknown> | unknown;
114
127
  hasRegisteredType<T>(source: Class<T> | string, type: Class<T> | string | TypedArray<T>, parent?: boolean): boolean;
@@ -1 +1 @@
1
- {"version":3,"file":"container.d.ts","sourceRoot":"","sources":["../../src/container.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"container.d.ts","sourceRoot":"","sources":["../../src/container.ts"],"names":[],"mappings":"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"}
@@ -1,5 +1,6 @@
1
1
  import { InvalidArgument } from '@spinajs/exceptions';
2
2
  import 'reflect-metadata';
3
+ import { TypedArray } from './array.js';
3
4
  import { DI_DESCRIPTION_SYMBOL } from './decorators.js';
4
5
  import { ResolveType } from './enums.js';
5
6
  import { getTypeName, isAsyncService, isFactory, isTypedArray, isPromise } from './helpers.js';
@@ -9,7 +10,7 @@ import { Binder } from './binder.js';
9
10
  import { Registry } from './registry.js';
10
11
  import { ContainerCache } from './container-cache.js';
11
12
  import _ from 'lodash';
12
- import { ResolveException, ServiceNotFound } from './exceptions.js';
13
+ import { ServiceNotFound } from './exceptions.js';
13
14
  /**
14
15
  * Dependency injection container implementation
15
16
  */
@@ -28,6 +29,10 @@ export class Container extends EventEmitter {
28
29
  }
29
30
  constructor(parent) {
30
31
  super();
32
+ /**
33
+ * Child containers created from this container
34
+ */
35
+ this.children = new Set();
31
36
  this.registry = new Registry(this);
32
37
  this.cache = new ContainerCache(this);
33
38
  this.parent = parent || undefined;
@@ -40,13 +45,31 @@ export class Container extends EventEmitter {
40
45
  this.clearRegistry();
41
46
  }
42
47
  async dispose() {
48
+ const disposalErrors = [];
49
+ // Dispose all children first
50
+ await Promise.all([...this.children].map(child => child.dispose().catch(err => {
51
+ disposalErrors.push(err);
52
+ // Continue with other children even if one fails
53
+ })));
54
+ this.children.clear();
55
+ // Dispose services in this container
43
56
  for (const entry of this.cache) {
44
57
  if (entry.value instanceof Service) {
45
- await entry.value.dispose();
58
+ try {
59
+ await entry.value.dispose();
60
+ }
61
+ catch (err) {
62
+ disposalErrors.push(err);
63
+ // Continue with other services even if one fails
64
+ }
46
65
  }
47
66
  }
48
67
  this.clearCache();
49
68
  this.emit('di.dispose');
69
+ // Log disposal errors if any occurred
70
+ if (disposalErrors.length > 0) {
71
+ console.warn(`${disposalErrors.length} services failed to dispose properly:`, disposalErrors);
72
+ }
50
73
  }
51
74
  /**
52
75
  * clears container registered types information
@@ -60,6 +83,22 @@ export class Container extends EventEmitter {
60
83
  clearRegistry() {
61
84
  this.Registry.clear();
62
85
  }
86
+ /**
87
+ * Get cache statistics for memory monitoring
88
+ */
89
+ getCacheStats() {
90
+ const entries = [];
91
+ let size = 0;
92
+ for (const entry of this.cache) {
93
+ entries.push(entry.key);
94
+ size++;
95
+ }
96
+ return {
97
+ size,
98
+ entries,
99
+ childrenCount: this.children.size
100
+ };
101
+ }
63
102
  /**
64
103
  * Register class/interface to DI.
65
104
  * @param type - interface object to register
@@ -85,14 +124,20 @@ export class Container extends EventEmitter {
85
124
  *
86
125
  */
87
126
  child() {
88
- return new Container(this);
127
+ const child = new Container(this);
128
+ this.children.add(child);
129
+ // Remove from parent when child is disposed
130
+ child.once('di.dispose', () => {
131
+ this.children.delete(child);
132
+ });
133
+ return child;
89
134
  }
90
135
  get(service, parent = true) {
91
136
  // get value registered as TypedArray ( mean to return all created instances )
92
- if (service instanceof Array && service.constructor.name === 'TypedArray') {
137
+ if (service instanceof Array && service.constructor.name === 'TypedArray' || service instanceof TypedArray) {
93
138
  return this.cache.get(getTypeName(service.Type));
94
139
  }
95
- const r = this.cache.get(service, parent);
140
+ const r = this.cache.get(this.getCurrentType(service, null, parent ?? true) ?? service, parent);
96
141
  return r[r.length - 1];
97
142
  }
98
143
  hasRegistered(service, parent = true) {
@@ -107,13 +152,16 @@ export class Container extends EventEmitter {
107
152
  * @throws {@link InvalidArgument} when service is null or empty
108
153
  */
109
154
  isResolved(service, parent = true) {
110
- return this.Cache.has(service, parent);
155
+ if (service instanceof Array && service.constructor.name === 'TypedArray' || service instanceof TypedArray) {
156
+ return this.Cache.has(this.getCurrentType(service.Type, null, parent ?? true) ?? service, parent);
157
+ }
158
+ return this.Cache.has(this.getCurrentType(service, null, parent ?? true) ?? service, parent);
111
159
  }
112
160
  /**
113
161
  *
114
162
  * @param type - type to resolve
115
163
  * @param options - options passed to constructor / factory
116
- * @param check - strict check if serivice is registered in container before resolving. Default behavior is to not check and resolve
164
+ * @param check - strict check if serivice is registered in container before resolving. Default behavior is not to check and resolve
117
165
  */
118
166
  resolve(type, options, check, tType) {
119
167
  if (!type) {
@@ -144,30 +192,15 @@ export class Container extends EventEmitter {
144
192
  }
145
193
  const resolved = targetType.map((r) => this.resolveType(type, r, opt));
146
194
  if (resolved.some((r) => r instanceof Promise)) {
147
- return Promise.all(resolved);
195
+ return Promise.all(resolved).then(() => this.get(type, check ?? true));
148
196
  }
149
- return resolved;
197
+ return this.get(type, check ?? true);
150
198
  }
151
199
  else {
152
- // finaly resolve single type:
153
- // 1. last registered type OR
154
- // 2. if non is registered - type itself
155
- let targetType = this.getRegisteredTypes(type);
156
- if (!targetType) {
157
- // if nothing is register under string identifier, then return null
158
- if (typeof type === 'string') {
159
- return null;
160
- }
161
- else {
162
- targetType = [type];
163
- }
200
+ const fType = this.getCurrentType(type, tType, check ?? true);
201
+ if (fType === null) {
202
+ return null;
164
203
  }
165
- // if we have target function callback
166
- // we can select whitch of targetType to resolve
167
- //
168
- // if not, by default last registered type is resolved
169
- // if we have override for target type in registry, resolve it ( last registered ) otherwise resolve target type type itself
170
- const fType = targetType[targetType.length - 1] ?? tType;
171
204
  const rValue = this.resolveType(sourceType, fType, opt);
172
205
  return rValue;
173
206
  }
@@ -175,6 +208,28 @@ export class Container extends EventEmitter {
175
208
  getRegisteredTypes(service, parent) {
176
209
  return this.Registry.getTypes(service, parent);
177
210
  }
211
+ getCurrentType(type, tType, check) {
212
+ // finaly resolve single type:
213
+ // 1. last registered type OR
214
+ // 2. if non is registered - type itself
215
+ let targetType = this.getRegisteredTypes(type, check ?? true);
216
+ if (!targetType) {
217
+ // if nothing is register under string identifier, then return null
218
+ if (typeof type === 'string') {
219
+ return null;
220
+ }
221
+ else {
222
+ targetType = [type];
223
+ }
224
+ }
225
+ // if we have target function callback
226
+ // we can select whitch of targetType to resolve
227
+ //
228
+ // if not, by default last registered type is resolved
229
+ // if we have override for target type in registry, resolve it ( last registered ) otherwise resolve target type type itself
230
+ const fType = targetType[targetType.length - 1] ?? tType;
231
+ return fType;
232
+ }
178
233
  resolveType(sourceType, targetType, options) {
179
234
  /**
180
235
  * If its a factory func, always resolve as new instance
@@ -192,11 +247,7 @@ export class Container extends EventEmitter {
192
247
  // resolving strategy per container is treatead as singleton
193
248
  // in this particular container
194
249
  const isSingletonInChild = descriptor.resolver === ResolveType.PerChildContainer;
195
- const isSingleton = descriptor.resolver === ResolveType.Singleton;
196
- const setCache = (target) => {
197
- this.Cache.add(sourceType, target);
198
- return target;
199
- };
250
+ const isSingleton = descriptor.resolver === ResolveType.Singleton || descriptor.resolver === ResolveType.PerInstanceCheck || descriptor.resolver === ResolveType.PerInstance;
200
251
  const emit = (target) => {
201
252
  const sourceTypeName = getTypeName(sourceType);
202
253
  const targetTypeName = getTypeName(targetType);
@@ -207,31 +258,15 @@ export class Container extends EventEmitter {
207
258
  this.emit(`di.resolved.${sourceTypeName}`, this, target);
208
259
  }
209
260
  };
210
- const getCachedInstance = (e, parent) => {
211
- if (this.isResolved(e, parent)) {
212
- const rArray = this.get(e, parent);
213
- return _.isArray(rArray) ? rArray.find((x) => getTypeName(x) === getTypeName(targetType)) : rArray;
214
- }
215
- return null;
216
- };
217
- const getCachedInstances = (e, parent) => {
218
- if (this.isResolved(e, parent)) {
219
- const rArray = this.get(e, parent);
220
- return _.isArray(rArray) ? rArray : [rArray];
221
- }
222
- return null;
223
- };
224
261
  const createNewInstance = (t, i, options) => {
225
262
  const instance = this.getNewInstance(t, i, options);
226
263
  if (isPromise(instance)) {
227
264
  return instance.then((r) => {
228
- setCache(r);
229
265
  emit(r);
230
266
  return r;
231
267
  });
232
268
  }
233
269
  else {
234
- setCache(instance);
235
270
  emit(instance);
236
271
  return instance;
237
272
  }
@@ -250,48 +285,27 @@ export class Container extends EventEmitter {
250
285
  return instance;
251
286
  }
252
287
  }
253
- if (d.resolver === ResolveType.PerInstanceCheck) {
254
- const cashed = getCachedInstances(tType, true);
255
- if (cashed) {
256
- const found = cashed.find((x) => {
257
- if (!x.__checkInstance__) {
258
- // eslint-disable-next-line @typescript-eslint/restrict-template-expressions
259
- throw new ResolveException(`service ${x.constructor.name} is marked as PerInstanceCheck resolver, but no __checkInstance__ function is provided`);
260
- }
261
- return x.__checkInstance__(options);
262
- });
263
- if (found) {
264
- return found;
265
- }
266
- else {
267
- return createNewInstance(t, i, options);
268
- }
269
- }
270
- }
271
288
  this.Registry.register(sName, t);
272
- const cashed = getCachedInstance(tType, d.resolver === ResolveType.Singleton ? true : false);
273
- if (!cashed) {
274
- return createNewInstance(t, i, options);
275
- }
276
- else {
277
- return cashed;
278
- }
289
+ // For singletons, don't check cache here - let getOrCreate handle it atomically
290
+ return createNewInstance(t, i, options);
279
291
  };
280
- // check cache if needed
292
+ // For singletons, use atomic cache operations to prevent concurrent creation
281
293
  if (isSingletonInChild || isSingleton) {
282
- // if its singleton ( not per child container )
283
- // check also in parent containers
284
- // ------- IMPORTANT ------------
285
- // TODO: in future allow to check in runtime if target type is cashed,
286
- // now, if for example we resolve array of some type,
287
- // when we later register another type of base class used in typed array
288
- // we will not resolve it, becaouse contaienr will not check
289
- // if in cache this new type exists ( only check if type in array exists )
290
- const cached = getCachedInstance(sourceType, isSingleton);
291
- if (cached) {
292
- return cached;
293
- }
294
+ return this.Cache.getOrCreate(sourceType, tType, () => {
295
+ const deps = this.resolveDependencies(descriptor.inject);
296
+ if (deps instanceof Promise) {
297
+ return deps.then((resolvedDependencies) => {
298
+ return resolve(descriptor, tType, resolvedDependencies);
299
+ });
300
+ }
301
+ else {
302
+ const resInstance = resolve(descriptor, tType, deps);
303
+ return resInstance;
304
+ }
305
+ }, true, // isSingleton
306
+ descriptor, options);
294
307
  }
308
+ // Non-singleton path - resolve normally without caching
295
309
  const deps = this.resolveDependencies(descriptor.inject);
296
310
  if (deps instanceof Promise) {
297
311
  return deps.then((resolvedDependencies) => {
@@ -300,9 +314,6 @@ export class Container extends EventEmitter {
300
314
  }
301
315
  else {
302
316
  const resInstance = resolve(descriptor, tType, deps);
303
- if (resInstance instanceof Promise) {
304
- return resInstance;
305
- }
306
317
  return resInstance;
307
318
  }
308
319
  }