@@ -28,6 +28,7 @@ class AutowirePass implements CompilerPassInterface
28
28
private $ definedTypes = array ();
29
29
private $ types ;
30
30
private $ notGuessableTypes = array ();
31
+ private $ usedTypes = array ();
31
32
32
33
/**
33
34
* {@inheritdoc}
@@ -56,6 +57,7 @@ public function process(ContainerBuilder $container)
56
57
$ this ->definedTypes = array ();
57
58
$ this ->types = null ;
58
59
$ this ->notGuessableTypes = array ();
60
+ $ this ->usedTypes = array ();
59
61
60
62
if (isset ($ e )) {
61
63
throw $ e ;
@@ -109,9 +111,11 @@ private function completeDefinition($id, Definition $definition)
109
111
110
112
if (isset ($ this ->types [$ typeHint ->name ]) && !isset ($ this ->notGuessableTypes [$ typeHint ->name ])) {
111
113
$ value = new Reference ($ this ->types [$ typeHint ->name ]);
114
+ $ this ->usedTypes [$ typeHint ->name ] = $ id ;
112
115
} else {
113
116
try {
114
117
$ value = $ this ->createAutowiredDefinition ($ typeHint , $ id );
118
+ $ this ->usedTypes [$ typeHint ->name ] = $ id ;
115
119
} catch (RuntimeException $ e ) {
116
120
if ($ parameter ->allowsNull ()) {
117
121
$ value = null ;
@@ -158,6 +162,8 @@ private function populateAvailableTypes()
158
162
*
159
163
* @param string $id
160
164
* @param Definition $definition
165
+ *
166
+ * @return array
161
167
*/
162
168
private function populateAvailableType ($ id , Definition $ definition )
163
169
{
@@ -172,16 +178,19 @@ private function populateAvailableType($id, Definition $definition)
172
178
}
173
179
174
180
if (!$ reflectionClass = $ this ->getReflectionClass ($ id , $ definition )) {
175
- return ;
181
+ return array () ;
176
182
}
177
183
184
+ $ types = array ();
178
185
foreach ($ reflectionClass ->getInterfaces () as $ reflectionInterface ) {
179
- $ this ->set ($ reflectionInterface ->name , $ id );
186
+ $ this ->set ($ types [] = $ reflectionInterface ->name , $ id );
180
187
}
181
188
182
189
do {
183
- $ this ->set ($ reflectionClass ->name , $ id );
190
+ $ this ->set ($ types [] = $ reflectionClass ->name , $ id );
184
191
} while ($ reflectionClass = $ reflectionClass ->getParentClass ());
192
+
193
+ return $ types ;
185
194
}
186
195
187
196
/**
@@ -243,7 +252,14 @@ private function createAutowiredDefinition(\ReflectionClass $typeHint, $id)
243
252
$ argumentDefinition = $ this ->container ->register ($ argumentId , $ typeHint ->name );
244
253
$ argumentDefinition ->setPublic (false );
245
254
246
- $ this ->populateAvailableType ($ argumentId , $ argumentDefinition );
255
+ foreach ($ this ->populateAvailableType ($ argumentId , $ argumentDefinition ) as $ type ) {
256
+ if (isset ($ this ->usedTypes [$ type ]) && isset ($ this ->notGuessableTypes [$ type ])) {
257
+ $ classOrInterface = interface_exists ($ type ) ? 'interface ' : 'class ' ;
258
+ $ matchingServices = implode (', ' , $ this ->types [$ type ]);
259
+
260
+ throw new RuntimeException (sprintf ('Unable to autowire argument of type "%s" for the service "%s". Multiple services exist for this %s (%s). ' , $ type , $ this ->usedTypes [$ type ], $ classOrInterface , $ matchingServices ), 1 );
261
+ }
262
+ }
247
263
248
264
try {
249
265
$ this ->completeDefinition ($ argumentId , $ argumentDefinition );
0 commit comments