From 31617f97b2e60b99cc7f33781b5e4f57722315a6 Mon Sep 17 00:00:00 2001 From: noniagriconomie Date: Thu, 15 Oct 2020 10:02:49 +0200 Subject: [PATCH] Improve/fix container doc --- service_container.rst | 70 ++++++++++++++++++++++++------------------- testing.rst | 2 +- 2 files changed, 40 insertions(+), 32 deletions(-) diff --git a/service_container.rst b/service_container.rst index ec3b67215c4..ff80ac27a14 100644 --- a/service_container.rst +++ b/service_container.rst @@ -32,15 +32,16 @@ service's class or interface name. Want to :doc:`log ` something? No p namespace App\Controller; use Psr\Log\LoggerInterface; + use Symfony\Component\HttpFoundation\Response; class ProductController { /** * @Route("/products") */ - public function list(LoggerInterface $logger) + public function list(LoggerInterface $logger): Response { - $logger->info('Look! I just used a service'); + $logger->info('Look, I just used a service!'); // ... } @@ -101,7 +102,7 @@ it can't be re-used. Instead, you decide to create a new class:: class MessageGenerator { - public function getHappyMessage() + public function getHappyMessage(): string { $messages = [ 'You did it! You updated the system! Amazing!', @@ -118,9 +119,14 @@ it can't be re-used. Instead, you decide to create a new class:: Congratulations! You've created your first service class! You can use it immediately inside your controller:: + // src/Controller/ProductController.php use App\Service\MessageGenerator; + use Symfony\Component\HttpFoundation\Response; - public function new(MessageGenerator $messageGenerator) + /** + * @Route("/products/new") + */ + public function new(MessageGenerator $messageGenerator): Response { // thanks to the type-hint, the container will instantiate a // new MessageGenerator and pass it to you! @@ -241,7 +247,7 @@ and use it later:: $this->logger = $logger; } - public function getHappyMessage() + public function getHappyMessage(): string { $this->logger->info('About to find a happy message!'); // ... @@ -291,8 +297,8 @@ Handling Multiple Services Suppose you also want to email a site administrator each time a site update is made. To do that, you create a new class:: - // src/Updates/SiteUpdateManager.php - namespace App\Updates; + // src/Service/SiteUpdateManager.php + namespace App\Service; use App\Service\MessageGenerator; use Symfony\Component\Mailer\MailerInterface; @@ -309,7 +315,7 @@ made. To do that, you create a new class:: $this->mailer = $mailer; } - public function notifyOfSiteUpdate() + public function notifyOfSiteUpdate(): bool { $happyMessage = $this->messageGenerator->getHappyMessage(); @@ -322,6 +328,8 @@ made. To do that, you create a new class:: $this->mailer->send($email); // ... + + return true; } } @@ -334,7 +342,7 @@ you can type-hint the new ``SiteUpdateManager`` class and use it:: namespace App\Controller; // ... - use App\Updates\SiteUpdateManager; + use App\Service\SiteUpdateManager; public function new(SiteUpdateManager $siteUpdateManager) { @@ -361,7 +369,7 @@ example, suppose you want to make the admin email configurable: .. code-block:: diff - // src/Updates/SiteUpdateManager.php + // src/Service/SiteUpdateManager.php // ... class SiteUpdateManager @@ -369,21 +377,21 @@ example, suppose you want to make the admin email configurable: // ... + private $adminEmail; - - public function __construct(MessageGenerator $messageGenerator, \Swift_Mailer $mailer) - + public function __construct(MessageGenerator $messageGenerator, \Swift_Mailer $mailer, $adminEmail) + - public function __construct(MessageGenerator $messageGenerator, MailerInterface $mailer) + + public function __construct(MessageGenerator $messageGenerator, MailerInterface $mailer, $adminEmail) { // ... + $this->adminEmail = $adminEmail; } - public function notifyOfSiteUpdate() + public function notifyOfSiteUpdate(): bool { // ... - $message = \Swift_Message::newInstance() + $email = (new Email()) // ... - - ->setTo('manager@example.com') - + ->setTo($this->adminEmail) + - ->to('manager@example.com') + + ->to($this->adminEmail) // ... ; // ... @@ -392,7 +400,7 @@ example, suppose you want to make the admin email configurable: If you make this change and refresh, you'll see an error: - Cannot autowire service "App\Updates\SiteUpdateManager": argument "$adminEmail" + Cannot autowire service "App\Service\SiteUpdateManager": argument "$adminEmail" of method "__construct()" must have a type-hint or be given a value explicitly. That makes sense! There is no way that the container knows what value you want to @@ -412,7 +420,7 @@ pass here. No problem! In your configuration, you can explicitly set this argume exclude: '../src/{DependencyInjection,Entity,Migrations,Tests,Kernel.php}' # explicitly configure the service - App\Updates\SiteUpdateManager: + App\Service\SiteUpdateManager: arguments: $adminEmail: 'manager@example.com' @@ -436,7 +444,7 @@ pass here. No problem! In your configuration, you can explicitly set this argume /> - + manager@example.com @@ -447,7 +455,7 @@ pass here. No problem! In your configuration, you can explicitly set this argume // config/services.php namespace Symfony\Component\DependencyInjection\Loader\Configurator; - use App\Updates\SiteUpdateManager; + use App\Service\SiteUpdateManager; return function(ContainerConfigurator $configurator) { // ... @@ -877,7 +885,7 @@ But, if you *do* need to make a service public, override the ``public`` setting: # ... same code as before # explicitly configure the service - Acme\PublicService: + App\Service\PublicService: public: true .. code-block:: xml @@ -893,7 +901,7 @@ But, if you *do* need to make a service public, override the ``public`` setting: - + @@ -902,13 +910,13 @@ But, if you *do* need to make a service public, override the ``public`` setting: // config/services.php namespace Symfony\Component\DependencyInjection\Loader\Configurator; - use Acme\PublicService; + use App\Service\PublicService; return function(ContainerConfigurator $configurator) { // ... same as code before // explicitly configure the service - $services->set(PublicService::class) + $services->set(Service\PublicService::class) ->public() ; }; @@ -1087,7 +1095,7 @@ admin email. In this case, each needs to have a unique service id: # this is the service's id site_update_manager.superadmin: - class: App\Updates\SiteUpdateManager + class: App\Service\SiteUpdateManager # you CAN still use autowiring: we just want to show what it looks like without autowire: false # manually wire all arguments @@ -1097,7 +1105,7 @@ admin email. In this case, each needs to have a unique service id: - 'superadmin@example.com' site_update_manager.normal_users: - class: App\Updates\SiteUpdateManager + class: App\Service\SiteUpdateManager autowire: false arguments: - '@App\Service\MessageGenerator' @@ -1106,7 +1114,7 @@ admin email. In this case, each needs to have a unique service id: # Create an alias, so that - by default - if you type-hint SiteUpdateManager, # the site_update_manager.superadmin will be used - App\Updates\SiteUpdateManager: '@site_update_manager.superadmin' + App\Service\SiteUpdateManager: '@site_update_manager.superadmin' .. code-block:: xml @@ -1120,19 +1128,19 @@ admin email. In this case, each needs to have a unique service id: - + superadmin@example.com - + contact@example.com - + @@ -1142,7 +1150,7 @@ admin email. In this case, each needs to have a unique service id: namespace Symfony\Component\DependencyInjection\Loader\Configurator; use App\Service\MessageGenerator; - use App\Updates\SiteUpdateManager; + use App\Service\SiteUpdateManager; return function(ContainerConfigurator $configurator) { // ... diff --git a/testing.rst b/testing.rst index 98dde991f9a..4b64d504631 100644 --- a/testing.rst +++ b/testing.rst @@ -599,7 +599,7 @@ it via that alias: namespace Symfony\Component\DependencyInjection\Loader\Configurator; use App\Service\MessageGenerator; - use App\Updates\SiteUpdateManager; + use App\Service\SiteUpdateManager; return function(ContainerConfigurator $configurator) { // ...