1111
1212trait Resolver
1313{
14+ /**
15+ * Build stack to detect cirular dependency.
16+ *
17+ * @var array
18+ */
19+ private array $ buildStack = [];
20+
1421 /**
1522 * Resolve the entry.
1623 *
@@ -72,7 +79,7 @@ protected function build($entry)
7279 * @param string $entry
7380 * @return object
7481 */
75- protected function autowire ($ entry )
82+ protected function autowire (string $ entry )
7683 {
7784 try {
7885 $ reflector = new ReflectionClass ($ entry );
@@ -90,10 +97,19 @@ protected function autowire($entry)
9097 return new $ entry ;
9198 }
9299
100+ // To Detect the circular dependency
101+ if (in_array ($ entry , $ this ->buildStack )) {
102+ throw new BindingException ("Circular dependency. " );
103+ }
104+
105+ $ this ->buildStack [] = $ entry ;
106+
93107 $ instances = $ this ->resolveDependencies (
94108 $ constructor ->getParameters ()
95109 );
96110
111+ array_pop ($ this ->buildStack );
112+
97113 return $ reflector ->newInstanceArgs ($ instances );
98114 }
99115
@@ -113,11 +129,9 @@ protected function resolveDependencies(array $dependencies)
113129 $ declaringClass = $ dependency ->getDeclaringClass ()->getName ();
114130
115131 if ($ type ->isBuiltin () || !$ type instanceof ReflectionNamedType) {
116- throw new BindingException ("Unresolvable dependency: resolving [ $ dependency] in class {$ declaringClass }" );
117- }
118-
119- if ($ this ->isCircularDependency ($ declaringClass , $ type )) {
120- throw new BindingException ("Circular dependency. " );
132+ throw new BindingException (
133+ "Unresolvable dependency: resolving [ $ dependency] in class {$ declaringClass }"
134+ );
121135 }
122136
123137 $ results [] = $ this ->resolve ($ type ->getName ());
@@ -126,24 +140,6 @@ protected function resolveDependencies(array $dependencies)
126140 return $ results ;
127141 }
128142
129- /**
130- * Check if there exists circular dependency.
131- *
132- * @param string $declaringClass
133- * @param ReflectionNamedType $type
134- * @return bool
135- */
136- protected function isCircularDependency (string $ declaringClass , ReflectionNamedType $ type )
137- {
138- if ($ declaringClass == $ type ->getName ()) {
139- return true ;
140- }
141-
142- $ autowire = new Autowire ($ type ->getName ());
143-
144- return $ autowire ->constructHasType ($ declaringClass );
145- }
146-
147143 /**
148144 * Check if the entry is shared or not.
149145 *
0 commit comments