Skip to content

Commit a76eb45

Browse files
committed
update
1 parent 1f6edd4 commit a76eb45

File tree

2 files changed

+51
-28
lines changed

2 files changed

+51
-28
lines changed

best_practices/security.rst

Lines changed: 3 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -328,18 +328,9 @@ the same ``getAuthorEmail()`` logic you used above:
328328
}
329329
}
330330
331-
To enable the security voter in the application, define a new service:
332-
333-
.. code-block:: yaml
334-
335-
# app/config/services.yml
336-
services:
337-
# ...
338-
app.post_voter:
339-
class: AppBundle\Security\PostVoter
340-
arguments: ['@security.access.decision_manager']
341-
public: false
342-
tags: [security.voter]
331+
Your application will :ref:`autoconfigure <services-autoconfigure>` your security
332+
voter and inject a ``AccessDecisionManagerInterface`` instance in it thanks to
333+
:doc:`autowiring </service_container/autowiring>`.
343334

344335
Now, you can use the voter with the ``@Security`` annotation:
345336

service_container/autowiring.rst

Lines changed: 48 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -86,13 +86,26 @@ autowired:
8686

8787
The autowiring subsystem will detect the dependencies of the ``TwitterClient``
8888
class 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 FQCN (fully-qualified
92+
class name) of the type hint, so here it'll search for a service named
93+
``AppBundle\Rot13Transformer``.
94+
95+
In case this service does not exist, the subsystem will detect the types of all
96+
services and check if one - and only one - implements the required type, and
97+
inject it if it's the case. If there are several services of the same type, an
98+
exception will be thrown. You'll have to use an explicit service definition or
99+
register a default implementation by creating a service or an alias whose id is
100+
the FQCN of the required type.
101+
Note that this check is deprecated and will be removed in 4.0. The subsystem
102+
will directly pass to the last option it has.
103+
104+
At last, if no service implements the required type, as it's the case here, the
105+
subsystem is, as long as it's a concrete class, smart enough to automatically
106+
register a private service for it.
107+
Here it'll register a private service for the ``Rot13Transformer`` class and set
108+
it as first argument of the ``twitter_client`` service.
96109

97110
As you can see, the autowiring feature drastically reduces the amount of configuration
98111
required to define a service. No more arguments section! It also makes it easy
@@ -185,7 +198,9 @@ And update ``TwitterClient`` to depend of this new interface::
185198
}
186199

187200
Finally the service definition must be updated because, obviously, the autowiring
188-
subsystem isn't able to find itself the interface implementation to register:
201+
subsystem isn't able to find itself the interface implementation to register.
202+
You have to indicate which service must be injected for your interface when
203+
using autowiring:
189204

190205
.. configuration-block::
191206

@@ -194,6 +209,10 @@ subsystem isn't able to find itself the interface implementation to register:
194209
services:
195210
AppBundle\Rot13Transformer: ~
196211
212+
# the ``AppBundle\Rot13Transformer`` service will be injected when
213+
# a ``AppBundle\TransformerInterface`` type-hint is detected
214+
AppBundle\TransformerInterface: '@AppBundle\Rot13Transformer'
215+
197216
AppBundle\TwitterClient:
198217
autowire: true
199218
@@ -207,6 +226,8 @@ subsystem isn't able to find itself the interface implementation to register:
207226
<services>
208227
<service id="AppBundle\Rot13Transformer" />
209228
229+
<service id="AppBundle\TransformerInterface" alias="AppBundle\Rot13Transformer" />
230+
210231
<service id="AppBundle\TwitterClient" autowire="true" />
211232
</services>
212233
</container>
@@ -218,21 +239,26 @@ subsystem isn't able to find itself the interface implementation to register:
218239
219240
// ...
220241
$container->register(Rot13Transformer::class);
242+
$container->setAlias(TransformerInterface::class, Rot13Transformer::class);
243+
221244
$container->autowire(TwitterClient::class);
222245
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.
246+
The autowiring subsystem knows that the ``AppBundle\Rot13Transformer`` service
247+
must be injected when dealing with the ``TransformerInterface`` and injects it
248+
automatically. Even when using interfaces (and you should), building the service
249+
graph and refactoring the project is easier than with standard definitions.
227250

228251
.. _service-autowiring-alias:
229252

230253
Dealing with Multiple Implementations of the Same Type
231254
------------------------------------------------------
232255

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::
256+
When you defined aliases whose id were FQCN earlier, you told the autowiring
257+
subsystem which service was the default implementation for those FQCN.
258+
So if you have several services implementing the same type, you can decide which
259+
one the subsystem should use. Let's introduce a new implementation of the
260+
``TransformerInterface`` returning the result of the ROT13 transformation
261+
uppercased::
236262

237263
namespace AppBundle;
238264

@@ -274,6 +300,9 @@ transformer::
274300
*/
275301
public function tweetAction(Request $request, TwitterClient $twitterClient)
276302
{
303+
// Here the client is directly injected because it's the default
304+
// implementation
305+
277306
return $this->tweet($request, $twitterClient);
278307
}
279308

@@ -315,6 +344,9 @@ and a Twitter client using it:
315344
services:
316345
AppBundle\Rot13Transformer: ~
317346
347+
# the ``AppBundle\Rot13Transformer`` service will *always* be used
348+
# when ``AppBundle\TransformerInterface`` is detected by the
349+
# autowiring subsystem
318350
AppBundle\TransformerInterface: '@AppBundle\Rot13Transformer'
319351
320352
AppBundle\TwitterClient:
@@ -359,7 +391,7 @@ and a Twitter client using it:
359391
360392
// ...
361393
$container->register(Rot13Transformer::class);
362-
$container->setAlias(TransformerInterface::class, Rot13Transformer::class)
394+
$container->setAlias(TransformerInterface::class, Rot13Transformer::class);
363395
364396
$container->autowire(TwitterClient::class);
365397
$container->autowire(UppercaseTransformer::class);

0 commit comments

Comments
 (0)