Skip to content

Commit cc3f107

Browse files
committed
feature #7883 More "id" => type hints / autowiring changes (weaverryan)
This PR was merged into the master branch. Discussion ---------- More "id" => type hints / autowiring changes Hi guys! I'm going through the docs to update things to the 3.3 features: autowiring, service `resource` loading, etc. This is just another step in this fairly significant change, so thoughts are warmly welcomed (and review is needed!) Thanks! Commits ------- e1d36e6 Going through more chapters to use types and autowiring
2 parents 51ad1f5 + e1d36e6 commit cc3f107

20 files changed

+276
-271
lines changed

controller/argument_value_resolver.rst

Lines changed: 20 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ Functionality Shipped with the HttpKernel
1616
-----------------------------------------
1717

1818
.. versionadded:: 3.3
19-
The ``SessionValueResolver`` was introduced in Symfony 3.3.
19+
The ``SessionValueResolver`` and ``ServiceValueResolver`` were both added in Symfony 3.3.
2020

2121
Symfony ships with five value resolvers in the HttpKernel component:
2222

@@ -27,6 +27,10 @@ Symfony ships with five value resolvers in the HttpKernel component:
2727
Injects the current ``Request`` if type-hinted with ``Request`` or a class
2828
extending ``Request``.
2929

30+
:class:`Symfony\\Component\\HttpKernel\\Controller\\ArgumentResolver\\ServiceValueResolver`
31+
Injects a service if type-hinted with a valid service class or interface. This
32+
works like :doc:`autowiring </service_container/autowiring>`.
33+
3034
:class:`Symfony\\Component\\HttpKernel\\Controller\\ArgumentResolver\\SessionValueResolver`
3135
Injects the configured session class extending ``SessionInterface`` if
3236
type-hinted with ``SessionInterface`` or a class extending
@@ -146,10 +150,12 @@ and adding a priority.
146150
147151
# app/config/services.yml
148152
services:
149-
app.value_resolver.user:
150-
class: AppBundle\ArgumentResolver\UserValueResolver
151-
arguments:
152-
- '@security.token_storage'
153+
_defaults:
154+
# ... be sure autowiring is enabled
155+
autowire: true
156+
# ...
157+
158+
AppBundle\ArgumentResolver\UserValueResolver:
153159
tags:
154160
- { name: controller.argument_value_resolver, priority: 50 }
155161
@@ -162,10 +168,11 @@ and adding a priority.
162168
xsi:schemaLocation="http://symfony.com/schema/dic/services http://symfony.com/schema/dic/services/services-1.0.xsd">
163169
164170
<services>
165-
<service id="app.value_resolver.user"
166-
class="AppBundle\ArgumentResolver\UserValueResolver"
167-
>
168-
<argument type="service" id="security.token_storage">
171+
<!-- ... be sure autowiring is enabled -->
172+
<defaults autowire="true" ... />
173+
<!-- ... -->
174+
175+
<service id="AppBundle\ArgumentResolver\UserValueResolver">
169176
<tag name="controller.argument_value_resolver" priority="50" />
170177
</service>
171178
</services>
@@ -175,14 +182,10 @@ and adding a priority.
175182
.. code-block:: php
176183
177184
// app/config/services.php
178-
use Symfony\Component\DependencyInjection\Definition;
179-
180-
$definition = new Definition(
181-
'AppBundle\ArgumentResolver\UserValueResolver',
182-
array(new Reference('security.token_storage'))
183-
);
184-
$definition->addTag('controller.argument_value_resolver', array('priority' => 50));
185-
$container->setDefinition('app.value_resolver.user', $definition);
185+
use AppBundle\ArgumentResolver\UserValueResolver;
186+
187+
$container->autowire(UserValueResolver::class)
188+
->addTag('controller.argument_value_resolver', array('priority' => 50));
186189
187190
While adding a priority is optional, it's recommended to add one to make sure
188191
the expected value is injected. The ``RequestAttributeValueResolver`` has a

controller/error_pages.rst

Lines changed: 17 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -269,9 +269,15 @@ In that case, you might want to override one or both of the ``showAction()`` and
269269
270270
# app/config/services.yml
271271
services:
272-
app.exception_controller:
273-
class: AppBundle\Controller\CustomExceptionController
274-
arguments: ['@twig', '%kernel.debug%']
272+
_defaults:
273+
# ... be sure autowiring is enabled
274+
autowire: true
275+
# ...
276+
277+
AppBundle\Controller\CustomExceptionController:
278+
public: true
279+
arguments:
280+
$debug: '%kernel.debug%'
275281
276282
.. code-block:: xml
277283
@@ -282,11 +288,12 @@ In that case, you might want to override one or both of the ``showAction()`` and
282288
xsi:schemaLocation="http://symfony.com/schema/dic/services http://symfony.com/schema/dic/services/services-1.0.xsd"
283289
>
284290
<services>
285-
<service id="app.exception_controller"
286-
class="AppBundle\Controller\CustomExceptionController"
287-
>
288-
<argument type="service" id="twig"/>
289-
<argument>%kernel.debug%</argument>
291+
<!-- ... be sure autowiring is enabled -->
292+
<defaults autowire="true" ... />
293+
<!-- ... -->
294+
295+
<service id="AppBundle\Controller\CustomExceptionController" public="true">
296+
<argument key="$debug">%kernel.debug%</argument>
290297
</service>
291298
</services>
292299
</container>
@@ -295,16 +302,9 @@ In that case, you might want to override one or both of the ``showAction()`` and
295302
296303
// app/config/services.php
297304
use AppBundle\Controller\CustomExceptionController;
298-
use Symfony\Component\DependencyInjection\Reference;
299-
300-
$container->register('app.exception_controller', CustomExceptionController::class)
301-
->setArguments(array(
302-
new Reference('twig'),
303-
'%kernel.debug%',
304-
));
305305
306-
And then configure ``twig.exception_controller`` using the controller as
307-
services syntax (e.g. ``app.exception_controller:showAction``).
306+
$container->autowire(CustomExceptionController::class)
307+
->setArgument('$debug', '%kernel.debug%');
308308
309309
.. tip::
310310

controller/soap_web_service.rst

Lines changed: 41 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -24,8 +24,8 @@ which represents the functionality that you'll expose in your SOAP service.
2424
In this case, the SOAP service will allow the client to call a method called
2525
``hello``, which happens to send an email::
2626

27-
// src/Acme/SoapBundle/Services/HelloService.php
28-
namespace Acme\SoapBundle\Services;
27+
// src/AppBundle/Service/HelloService.php
28+
namespace AppBundle\Service;
2929

3030
class HelloService
3131
{
@@ -50,56 +50,72 @@ In this case, the SOAP service will allow the client to call a method called
5050
}
5151
}
5252

53-
Next, you can train Symfony to be able to create an instance of this class.
54-
Since the class sends an email, it's been designed to accept a ``Swift_Mailer``
55-
instance. Using the Service Container, you can configure Symfony to construct
56-
a ``HelloService`` object properly:
53+
Next, make sure that your new class is registered as a service. If you use
54+
:doc:`autowiring </service_container/autowiring>` (enabled by default in the Symfony
55+
Standard Edition), this is easy:
5756

5857
.. configuration-block::
5958

6059
.. code-block:: yaml
6160
6261
# app/config/services.yml
6362
services:
64-
hello_service:
65-
class: Acme\SoapBundle\Services\HelloService
66-
arguments: ['@mailer']
63+
_defaults:
64+
# ... be sure autowiring is enabled
65+
autowire: true
66+
# ...
67+
68+
# add Service/ to the list of directories to load services from
69+
AppBundle\:
70+
resource: '../../src/AppBundle/{Service,Updates,Command,Form,EventSubscriber,Twig,Security}'
6771
6872
.. code-block:: xml
6973
7074
<!-- app/config/services.xml -->
71-
<services>
72-
<service id="hello_service" class="Acme\SoapBundle\Services\HelloService">
73-
<argument type="service" id="mailer"/>
74-
</service>
75-
</services>
75+
<?xml version="1.0" encoding="UTF-8" ?>
76+
<container xmlns="http://symfony.com/schema/dic/services"
77+
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
78+
xsi:schemaLocation="http://symfony.com/schema/dic/services
79+
http://symfony.com/schema/dic/services/services-1.0.xsd">
80+
81+
<services>
82+
<!-- ... be sure autowiring is enabled -->
83+
<defaults autowire="true" ... />
84+
<!-- ... -->
85+
86+
<!-- add Service/ to the list of directories to load services from -->
87+
<prototype namespace="AppBundle\" resource="../../src/AppBundle/{Service,Updates,Command,Form,EventSubscriber,Twig,Security}" />
88+
</services>
89+
</container>
7690
7791
.. code-block:: php
7892
7993
// app/config/services.php
80-
use Acme\SoapBundle\Services\HelloService;
94+
use AppBundle\Service\HelloService;
8195
82-
$container
83-
->register('hello_service', HelloService::class)
84-
->addArgument(new Reference('mailer'));
96+
$container->autowire(HelloService::class)
97+
->setPublic(false);
8598
8699
Below is an example of a controller that is capable of handling a SOAP
87-
request. If ``indexAction()`` is accessible via the route ``/soap``, then the
88-
WSDL document can be retrieved via ``/soap?wsdl``.
89-
90-
.. code-block:: php
100+
request. Because ``indexAction()`` is accessible via ``/soap``, the WSDL document
101+
can be retrieved via ``/soap?wsdl``::
91102

92-
namespace Acme\SoapBundle\Controller;
103+
namespace AppBundle\Controller;
93104

94105
use Symfony\Bundle\FrameworkBundle\Controller\Controller;
95106
use Symfony\Component\HttpFoundation\Response;
107+
use Sensio\Bundle\FrameworkExtraBundle\Configuration\Route;
108+
use AppBundle\Service\HelloService;
96109

97110
class HelloServiceController extends Controller
98111
{
99-
public function indexAction()
112+
/**
113+
* @Route("/soap")
114+
*/
115+
public function indexAction(HelloService $helloService)
100116
{
101117
$server = new \SoapServer('/path/to/hello.wsdl');
102-
$server->setObject($this->get('hello_service'));
118+
$server->setObject($helloService);
103119

104120
$response = new Response();
105121
$response->headers->set('Content-Type', 'text/xml; charset=ISO-8859-1');

controller/upload_file.rst

Lines changed: 49 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -221,8 +221,8 @@ Creating an Uploader Service
221221
To avoid logic in controllers, making them big, you can extract the upload
222222
logic to a separate service::
223223

224-
// src/AppBundle/FileUploader.php
225-
namespace AppBundle;
224+
// src/AppBundle/Service/FileUploader.php
225+
namespace AppBundle\Service;
226226

227227
use Symfony\Component\HttpFoundation\File\UploadedFile;
228228

@@ -259,47 +259,51 @@ Then, define a service for this class:
259259
# app/config/services.yml
260260
services:
261261
# ...
262-
app.brochure_uploader:
263-
class: AppBundle\FileUploader
264-
arguments: ['%brochures_directory%']
262+
263+
AppBundle\Service\FileUploader:
264+
arguments:
265+
$targetDir: '%brochures_directory%'
265266
266267
.. code-block:: xml
267268
268-
<!-- app/config/config.xml -->
269+
<!-- app/config/services.xml -->
269270
<?xml version="1.0" encoding="UTF-8" ?>
270271
<container xmlns="http://symfony.com/schema/dic/services"
271272
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
272273
xsi:schemaLocation="http://symfony.com/schema/dic/services
273-
http://symfony.com/schema/dic/services/services-1.0.xsd"
274-
>
275-
<!-- ... -->
274+
http://symfony.com/schema/dic/services/services-1.0.xsd">
276275
277-
<service id="app.brochure_uploader" class="AppBundle\FileUploader">
278-
<argument>%brochures_directory%</argument>
279-
</service>
276+
<services>
277+
<!-- ... -->
278+
279+
<service id="AppBundle\Service\FileUploader">
280+
<argument key="$targetDir">%brochures_directory%</argument>
281+
</service>
282+
</services>
280283
</container>
281284
282285
.. code-block:: php
283286
284287
// app/config/services.php
285-
use AppBundle\FileUploader;
288+
use AppBundle\Service\FileUploader;
286289
287-
// ...
288-
$container->register('app.brochure_uploader', FileUploader::class)
289-
->addArgument('%brochures_directory%');
290+
$container->autowire(FileUploader::class)
291+
->setArgument('$targetDir', '%brochures_directory%');
290292
291293
Now you're ready to use this service in the controller::
292294

293295
// src/AppBundle/Controller/ProductController.php
296+
use Symfony\Component\HttpFoundation\Request;
297+
use AppBundle\Service\FileUploader;
294298

295299
// ...
296-
public function newAction(Request $request)
300+
public function newAction(Request $request, FileUploader $fileUploader)
297301
{
298302
// ...
299303

300304
if ($form->isSubmitted() && $form->isValid()) {
301305
$file = $product->getBrochure();
302-
$fileName = $this->get('app.brochure_uploader')->upload($file);
306+
$fileName = $fileUploader->upload($file);
303307

304308
$product->setBrochure($fileName);
305309

@@ -323,7 +327,7 @@ automatically upload the file when persisting the entity::
323327
use Doctrine\ORM\Event\LifecycleEventArgs;
324328
use Doctrine\ORM\Event\PreUpdateEventArgs;
325329
use AppBundle\Entity\Product;
326-
use AppBundle\FileUploader;
330+
use AppBundle\Service\FileUploader;
327331

328332
class BrochureUploadListener
329333
{
@@ -375,10 +379,12 @@ Now, register this class as a Doctrine listener:
375379
376380
# app/config/services.yml
377381
services:
382+
_defaults:
383+
# ... be sure autowiring is enabled
384+
autowire: true
378385
# ...
379-
app.doctrine_brochure_listener:
380-
class: AppBundle\EventListener\BrochureUploadListener
381-
arguments: ['@app.brochure_uploader']
386+
387+
AppBundle\EventListener\BrochureUploadListener:
382388
tags:
383389
- { name: doctrine.event_listener, event: prePersist }
384390
- { name: doctrine.event_listener, event: preUpdate }
@@ -392,33 +398,44 @@ Now, register this class as a Doctrine listener:
392398
xsi:schemaLocation="http://symfony.com/schema/dic/services
393399
http://symfony.com/schema/dic/services/services-1.0.xsd"
394400
>
395-
<!-- ... -->
396-
397-
<service id="app.doctrine_brochure_listener"
398-
class="AppBundle\EventListener\BrochureUploaderListener"
399-
>
400-
<argument type="service" id="app.brochure_uploader"/>
401-
402-
<tag name="doctrine.event_listener" event="prePersist"/>
403-
<tag name="doctrine.event_listener" event="preUpdate"/>
404-
</service>
401+
<services>
402+
<!-- ... be sure autowiring is enabled -->
403+
<defaults autowire="true" ... />
404+
<!-- ... -->
405+
406+
<service id="AppBundle\EventListener\BrochureUploaderListener">
407+
<tag name="doctrine.event_listener" event="prePersist"/>
408+
<tag name="doctrine.event_listener" event="preUpdate"/>
409+
</service>
410+
</services>
405411
</container>
406412
407413
.. code-block:: php
408414
409415
// app/config/services.php
410416
use AppBundle\EventListener\BrochureUploaderListener;
417+
<<<<<<< HEAD
411418
use Symfony\Component\DependencyInjection\Reference;
412419

413420
// ...
414421
$container->register('app.doctrine_brochure_listener', BrochureUploaderListener::class)
415422
->addArgument(new Reference('brochures_directory'))
423+
=======
424+
425+
$container->autowire(BrochureUploaderListener::class)
426+
>>>>>>> 8974c4842... Going through more chapters to use types and autowiring
416427
->addTag('doctrine.event_listener', array(
417428
'event' => 'prePersist',
418429
))
419430
->addTag('doctrine.event_listener', array(
431+
<<<<<<< HEAD
420432
'event' => 'prePersist',
421433
));
434+
=======
435+
'event' => 'preUpdate',
436+
))
437+
;
438+
>>>>>>> 8974c4842... Going through more chapters to use types and autowiring
422439

423440
This listener is now automatically executed when persisting a new Product
424441
entity. This way, you can remove everything related to uploading from the

0 commit comments

Comments
 (0)