@@ -40,7 +40,7 @@ class Container
40
40
/** @var object[] service name => instance */
41
41
private $ instances = [];
42
42
43
- /** @var array circular reference detector */
43
+ /** @var array<string, true> circular reference detector */
44
44
private $ creating ;
45
45
46
46
/** @var array<string, string|\Closure> */
@@ -66,7 +66,9 @@ public function getParameters(): array
66
66
public function getParameter ($ key )
67
67
{
68
68
if (!array_key_exists ($ key , $ this ->parameters )) {
69
- $ this ->parameters [$ key ] = $ this ->getDynamicParameter ($ key );
69
+ $ this ->parameters [$ key ] = $ this ->preventDeadLock ("% $ key% " , function () use ($ key ) {
70
+ return $ this ->getDynamicParameter ($ key );
71
+ });
70
72
}
71
73
return $ this ->parameters [$ key ];
72
74
}
@@ -219,28 +221,21 @@ public function createService(string $name, array $args = []): object
219
221
{
220
222
$ name = $ this ->aliases [$ name ] ?? $ name ;
221
223
$ method = self ::getMethodName ($ name );
222
- $ cb = $ this ->methods [$ method ] ?? null ;
223
- if (isset ($ this ->creating [$ name ])) {
224
- throw new Nette \InvalidStateException (sprintf ('Circular reference detected for services: %s. ' , implode (', ' , array_keys ($ this ->creating ))));
225
-
226
- } elseif ($ cb === null ) {
224
+ $ callback = $ this ->methods [$ method ] ?? null ;
225
+ if ($ callback === null ) {
227
226
throw new MissingServiceException (sprintf ("Service '%s' not found. " , $ name ));
228
227
}
229
228
230
- try {
231
- $ this ->creating [$ name ] = true ;
232
- $ service = $ cb instanceof \Closure
233
- ? $ cb (...$ args )
229
+ $ service = $ this ->preventDeadLock ($ name , function () use ($ callback , $ args , $ method ) {
230
+ return $ callback instanceof \Closure
231
+ ? $ callback (...$ args )
234
232
: $ this ->$ method (...$ args );
235
-
236
- } finally {
237
- unset($ this ->creating [$ name ]);
238
- }
233
+ });
239
234
240
235
if (!is_object ($ service )) {
241
236
throw new Nette \UnexpectedValueException (sprintf (
242
237
"Unable to create service ' $ name', value returned by %s is not object. " ,
243
- $ cb instanceof \Closure ? 'closure ' : "method $ method() "
238
+ $ callback instanceof \Closure ? 'closure ' : "method $ method() "
244
239
));
245
240
}
246
241
@@ -326,6 +321,20 @@ public function findByTag(string $tag): array
326
321
}
327
322
328
323
324
+ private function preventDeadLock (string $ key , \Closure $ callback )
325
+ {
326
+ if (isset ($ this ->creating [$ key ])) {
327
+ throw new Nette \InvalidStateException (sprintf ('Circular reference detected for: %s. ' , implode (', ' , array_keys ($ this ->creating ))));
328
+ }
329
+ try {
330
+ $ this ->creating [$ key ] = true ;
331
+ return $ callback ();
332
+ } finally {
333
+ unset($ this ->creating [$ key ]);
334
+ }
335
+ }
336
+
337
+
329
338
/********************* autowiring ****************d*g**/
330
339
331
340
0 commit comments