@@ -30,8 +30,11 @@ public function __construct(
3030 /** @var ArrayIterator<array-key, mixed> $definitions */
3131 private(set) ArrayIterator $ definitions = new ArrayIterator (),
3232
33- /** @var ArrayIterator<array-key, mixed> $singletons */
34- private(set) ArrayIterator $ singletons = new ArrayIterator (),
33+ /** @var ArrayIterator<array-key, mixed> $singletonDefinitions */
34+ private(set) ArrayIterator $ singletonDefinitions = new ArrayIterator (),
35+
36+ /** @var ArrayIterator<array-key, object> $resolvedSingletons */
37+ private(set) ArrayIterator $ resolvedSingletons = new ArrayIterator (),
3538
3639 /** @var ArrayIterator<array-key, class-string> $initializers */
3740 private(set) ArrayIterator $ initializers = new ArrayIterator (),
@@ -61,7 +64,7 @@ public function setDefinitions(array $definitions): self
6164
6265 public function setSingletons (array $ singletons ): self
6366 {
64- $ this ->singletons = new ArrayIterator ($ singletons );
67+ $ this ->resolvedSingletons = new ArrayIterator ($ singletons );
6568
6669 return $ this ;
6770 }
@@ -97,7 +100,7 @@ public function getDefinitions(): array
97100 */
98101 public function getSingletons (?string $ interface = null ): array
99102 {
100- $ singletons = $ this ->singletons ->getArrayCopy ();
103+ $ singletons = $ this ->resolvedSingletons ->getArrayCopy ();
101104
102105 if (is_null ($ interface )) {
103106 return $ singletons ;
@@ -134,24 +137,34 @@ public function register(string $className, callable $definition): self
134137
135138 public function unregister (string $ className , bool $ tagged = false ): self
136139 {
137- unset($ this ->definitions [$ className ], $ this ->singletons [$ className ]);
140+ unset($ this ->definitions [$ className ]);
141+ unset($ this ->singletonDefinitions [$ className ]);
142+ unset($ this ->resolvedSingletons [$ className ]);
138143
139144 if ($ tagged ) {
140- $ singletons = array_filter (
141- array: $ this ->getSingletons (),
142- callback: static fn (mixed $ _ , string $ key ) => ! str_starts_with ($ key , "{$ className }# " ),
143- mode: \ARRAY_FILTER_USE_BOTH ,
144- );
145+ foreach ($ this ->singletonDefinitions as $ key => $ definition ) {
146+ if (! str_starts_with ($ key , "{$ className }# " )) {
147+ continue ;
148+ }
149+
150+ unset($ this ->singletonDefinitions [$ key ]);
151+ }
145152
146- $ this ->setSingletons ($ singletons );
153+ foreach ($ this ->resolvedSingletons as $ key => $ definition ) {
154+ if (! str_starts_with ($ key , "{$ className }# " )) {
155+ continue ;
156+ }
157+
158+ unset($ this ->resolvedSingletons [$ key ]);
159+ }
147160 }
148161
149162 return $ this ;
150163 }
151164
152165 public function has (string $ className , null |string |UnitEnum $ tag = null ): bool
153166 {
154- return isset ($ this ->definitions [$ className ]) || isset ($ this ->singletons [$ this ->resolveTaggedName ($ className , $ tag )]);
167+ return isset ($ this ->definitions [$ className ]) || isset ($ this ->singletonDefinitions [$ this ->resolveTaggedName ($ className , $ tag )]);
155168 }
156169
157170 public function singleton (string $ className , mixed $ definition , null |string |UnitEnum $ tag = null ): self
@@ -160,9 +173,9 @@ public function singleton(string $className, mixed $definition, null|string|Unit
160173 $ tag = $ definition ->tag ;
161174 }
162175
163- $ className = $ this ->resolveTaggedName ($ className , $ tag );
176+ $ dependencyName = $ this ->resolveTaggedName ($ className , $ tag );
164177
165- $ this ->singletons [ $ className ] = $ definition ;
178+ $ this ->singletonDefinitions [ $ dependencyName ] = $ definition ;
166179
167180 return $ this ;
168181 }
@@ -350,12 +363,18 @@ private function resolveDependency(string $className, null|string|UnitEnum $tag
350363
351364 $ dependencyName = $ this ->resolveTaggedName ($ className , $ tag );
352365
366+ // Check if a resolved singleton is present
367+ if ($ instance = $ this ->resolvedSingletons [$ dependencyName ] ?? null ) {
368+ $ this ->resolveChain ()->add ($ class );
369+
370+ return $ instance ;
371+ }
372+
353373 // Check if the class has been registered as a singleton.
354- if ($ instance = $ this ->singletons [$ dependencyName ] ?? null ) {
355- if ($ instance instanceof Closure) {
356- $ instance = $ instance ($ this );
357- $ this ->singletons [$ className ] = $ instance ;
358- }
374+ if ($ singletonDefinition = $ this ->singletonDefinitions [$ dependencyName ] ?? null ) {
375+ $ instance = $ singletonDefinition instanceof Closure ? $ singletonDefinition ($ this ) : $ singletonDefinition ;
376+
377+ $ this ->resolvedSingletons [$ dependencyName ] = $ instance ;
359378
360379 $ this ->resolveChain ()->add ($ class );
361380
@@ -696,6 +715,8 @@ public function addResettable(string|ClassReflector $resettableClass): Container
696715
697716 public function reset (): self
698717 {
718+ $ this ->resolvedSingletons = new ArrayIterator ();
719+
699720 foreach ($ this ->resettables as $ resettableClass ) {
700721 /** @var Resettable $resettable */
701722 $ resettable = $ this ->get ($ resettableClass );
0 commit comments