@@ -86,13 +86,27 @@ autowired:
8686
8787The autowiring subsystem will detect the dependencies of the ``TwitterClient ``
8888class by parsing its constructor. For instance it will find here an instance of
89- a ``Rot13Transformer `` as dependency. If an existing service definition (and only
90- one – see below) is of the required type, this service will be injected. If it's
91- not the case (like in this example), the subsystem is smart enough to automatically
92- register a private service for the ``Rot13Transformer `` class and set it as first
93- argument of the ``twitter_client `` service. Again, it can work only if there is one
94- class of the given type. If there are several classes of the same type, you must
95- use an explicit service definition or register a default implementation.
89+ a ``Rot13Transformer `` as dependency.
90+
91+ The subsystem will first try to find a service whose id is the required type, so
92+ here it'll search for a service named ``AppBundle\Rot13Transformer ``.
93+ It will be considered as the default implementation and will win over any other
94+ services implementing the required type.
95+
96+ *In case this service does not exist *, the subsystem will detect the types of
97+ all services and check if one - and only one - implements the required type, and
98+ inject it if it's the case. If there are several services of the same type, an
99+ exception will be thrown. You'll have to use an explicit service definition or
100+ register a default implementation by creating a service or an alias whose id is
101+ the required type (as seen above).
102+ Note that this step is deprecated and will no longer be done in 4.0. The
103+ subsystem will directly pass to the third check.
104+
105+ At last, if no service implements the required type, as it's the case here, the
106+ subsystem is, as long as it's a concrete class, smart enough to automatically
107+ register a private service for it.
108+ Here it'll register a private service for the ``Rot13Transformer `` class and set
109+ it as first argument of the ``twitter_client `` service.
96110
97111As you can see, the autowiring feature drastically reduces the amount of configuration
98112required to define a service. No more arguments section! It also makes it easy
@@ -185,7 +199,9 @@ And update ``TwitterClient`` to depend of this new interface::
185199 }
186200
187201Finally the service definition must be updated because, obviously, the autowiring
188- subsystem isn't able to find itself the interface implementation to register:
202+ subsystem isn't able to find itself the interface implementation to register.
203+ You have to indicate which service must be injected for your interface when
204+ using autowiring:
189205
190206.. configuration-block ::
191207
@@ -194,6 +210,10 @@ subsystem isn't able to find itself the interface implementation to register:
194210 services :
195211 AppBundle\Rot13Transformer : ~
196212
213+ # the ``AppBundle\Rot13Transformer`` service will be injected when
214+ # a ``AppBundle\TransformerInterface`` type-hint is detected
215+ AppBundle\TransformerInterface : ' @AppBundle\Rot13Transformer'
216+
197217 AppBundle\TwitterClient :
198218 autowire : true
199219
@@ -207,32 +227,43 @@ subsystem isn't able to find itself the interface implementation to register:
207227 <services >
208228 <service id =" AppBundle\Rot13Transformer" />
209229
230+ <service id =" AppBundle\TransformerInterface" alias =" AppBundle\Rot13Transformer" />
231+
210232 <service id =" AppBundle\TwitterClient" autowire =" true" />
211233 </services >
212234 </container >
213235
214236 .. code-block :: php
215237
216238 use AppBundle\Rot13Transformer;
239+ use AppBundle\TransformerInterface;
217240 use AppBundle\TwitterClient;
218241
219242 // ...
220243 $container->register(Rot13Transformer::class);
244+ $container->setAlias(TransformerInterface::class, Rot13Transformer::class);
245+
221246 $container->autowire(TwitterClient::class);
222247
223- The autowiring subsystem detects that the ``AppBundle\Rot13Transformer `` service
224- implements the ``TransformerInterface `` and injects it automatically. Even when
225- using interfaces (and you should), building the service graph and refactoring
226- the project is easier than with standard definitions.
248+ Thanks to the ``AppBundle\TransformerInterface `` alias, the autowiring subsystem
249+ knows that the ``AppBundle\Rot13Transformer `` service must be injected when
250+ dealing with the ``TransformerInterface `` and injects it automatically. Even
251+ when using interfaces (and you should), building the service graph and
252+ refactoring the project is easier than with standard definitions.
227253
228254.. _service-autowiring-alias :
229255
230256Dealing with Multiple Implementations of the Same Type
231257------------------------------------------------------
232258
233- Last but not least, the autowiring feature allows to specify the default implementation
234- of a given type. Let's introduce a new implementation of the ``TransformerInterface ``
235- returning the result of the ROT13 transformation uppercased::
259+ To deal with multiple implementations of the same type, the manipulation is the
260+ same as when dealing with an interface. You have to register a service whose id
261+ is your type: this will indicate to the autowiring subsystem which service to
262+ use by default for this type.
263+ So if you have several services implementing the same type, you can decide which
264+ one the subsystem should use. Let's introduce a new implementation of the
265+ ``TransformerInterface `` returning the result of the ROT13 transformation
266+ uppercased::
236267
237268 namespace AppBundle;
238269
@@ -274,6 +305,9 @@ transformer::
274305 */
275306 public function tweetAction(Request $request, TwitterClient $twitterClient)
276307 {
308+ // Here the client is automatically injected because it's the default
309+ // implementation
310+
277311 return $this->tweet($request, $twitterClient);
278312 }
279313
@@ -315,6 +349,9 @@ and a Twitter client using it:
315349 services :
316350 AppBundle\Rot13Transformer : ~
317351
352+ # the ``AppBundle\Rot13Transformer`` service will *always* be used
353+ # when ``AppBundle\TransformerInterface`` is detected by the
354+ # autowiring subsystem
318355 AppBundle\TransformerInterface : ' @AppBundle\Rot13Transformer'
319356
320357 AppBundle\TwitterClient :
@@ -359,16 +396,16 @@ and a Twitter client using it:
359396
360397 // ...
361398 $container->register(Rot13Transformer::class);
362- $container->setAlias(TransformerInterface::class, Rot13Transformer::class)
399+ $container->setAlias(TransformerInterface::class, Rot13Transformer::class);
363400
364401 $container->autowire(TwitterClient::class);
365402 $container->autowire(UppercaseTransformer::class);
366403 $container->register('uppercase_twitter_client', TwitterClient::class)
367404 ->addArgument(new Reference(UppercaseTransformer::class));
368405
369406 This deserves some explanations. You now have two services implementing the
370- ``TransformerInterface ``. The autowiring subsystem cannot guess which one
371- to use which leads to errors like this:
407+ ``TransformerInterface ``. As said earlier, the autowiring subsystem cannot guess
408+ which one to use which leads to errors like this:
372409
373410.. code-block :: text
374411
0 commit comments