From f32aec1dc00e15dcddb41e10a746959c22d8e971 Mon Sep 17 00:00:00 2001 From: Kevin Bond Date: Fri, 18 Mar 2022 11:09:53 -0400 Subject: [PATCH 1/2] [DI][HttpKernel] document `Autowire` attribute --- controller.rst | 41 ++++++++++++++++++++++++++++++++++- service_container.rst | 50 +++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 90 insertions(+), 1 deletion(-) diff --git a/controller.rst b/controller.rst index a7ddd67c3e9..c1510ba6896 100644 --- a/controller.rst +++ b/controller.rst @@ -153,7 +153,7 @@ and ``redirect()`` methods:: // redirects to a route and maintains the original query string parameters return $this->redirectToRoute('blog_show', $request->query->all()); - + // redirects to the current route (e.g. for Post/Redirect/Get pattern): return $this->redirectToRoute($request->attributes->get('_route')); @@ -286,6 +286,45 @@ in your controllers. For more information about services, see the :doc:`/service_container` article. +Autowire Parameter Attribute +~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +.. versionadded:: 6.1 + + The ``#[Autowire]`` attribute was introduced in Symfony 6.1. + +Services that cannot be autowired, :ref:`parameters ` and even +:doc:`complex expressions ` can be bound +to a controller argument with the ``#[Autowire]`` attribute:: + + use Psr\Log\LoggerInterface; + use Symfony\Component\DependencyInjection\Attribute\Autowire; + use Symfony\Component\HttpFoundation\Response; + // ... + + /** + * @Route("/lucky/number/{max}") + */ + public function number( + int $max, + + #[Autowire('@monolog.logger.request')] + LoggerInterface $logger, + + #[Autowire('%kernel.project_dir%/data')] + string $dataDir, + + #[Autowire('%kernel.debug%')] + bool $debugMode, + + #[Autowire("@=service("App\\Mail\\MailerConfiguration").getMailerMethod()")] + string $mailerMethod, + ): Response + { + $logger->info('We are logging!'); + // ... + } + Generating Controllers ---------------------- diff --git a/service_container.rst b/service_container.rst index 6b6015a02e8..4e613c90708 100644 --- a/service_container.rst +++ b/service_container.rst @@ -687,6 +687,56 @@ For a full list of *all* possible services in the container, run: .. _services-binding: +Autowire Parameter Attribute +---------------------------- + +.. versionadded:: 6.1 + + The ``#[Autowire]`` attribute was introduced in Symfony 6.1. + +For services that cannot be autowired, you can use the ``#[Autowire]`` parameter +attribute to explicitly configure the service:: + + // src/Service/MessageGenerator.php + namespace App\Service; + + use Psr\Log\LoggerInterface; + use Symfony\Component\DependencyInjection\Attribute\Autowire; + + class MessageGenerator + { + public function __construct( + #[Autowire('@monolog.logger.request')] private LoggerInterface $logger + ) { + } + // ... + } + +The ``#[Autowire]`` can also be used for :ref:`parameters ` and even +:doc:`complex expressions `:: + + // src/Service/MessageGenerator.php + namespace App\Service; + + use Psr\Log\LoggerInterface; + use Symfony\Component\DependencyInjection\Attribute\Autowire; + + class MessageGenerator + { + public function __construct( + #[Autowire('%kernel.project_dir%/data')] + private string $dataDir, + + #[Autowire('%kernel.debug%')] + private bool $debugMode, + + #[Autowire("@=service("App\\Mail\\MailerConfiguration").getMailerMethod()")] + private string $mailerMethod, + ) { + } + // ... + } + Binding Arguments by Name or Type --------------------------------- From bf8be7e848041b82db92dc083f6216b1d98bdea6 Mon Sep 17 00:00:00 2001 From: Wouter de Jong Date: Sun, 1 May 2022 16:53:31 +0200 Subject: [PATCH 2/2] Move the autowire attribute sections --- controller.rst | 125 ++++++++----------------------- service_container.rst | 50 ------------- service_container/autowiring.rst | 56 +++++++++++++- 3 files changed, 86 insertions(+), 145 deletions(-) diff --git a/controller.rst b/controller.rst index c1510ba6896..a0bb1d3ffb5 100644 --- a/controller.rst +++ b/controller.rst @@ -223,107 +223,46 @@ command: $ php bin/console debug:autowiring -If you need control over the *exact* value of an argument, you can :ref:`bind ` -the argument by its name: - -.. configuration-block:: - - .. code-block:: yaml - - # config/services.yaml - services: - # ... - - # explicitly configure the service - App\Controller\LuckyController: - tags: [controller.service_arguments] - bind: - # for any $logger argument, pass this specific service - $logger: '@monolog.logger.doctrine' - # for any $projectDir argument, pass this parameter value - $projectDir: '%kernel.project_dir%' - - .. code-block:: xml - - - - - - - - - - - - - %kernel.project_dir% - - - - - .. code-block:: php - - // config/services.php - use App\Controller\LuckyController; - use Symfony\Component\DependencyInjection\Reference; - - $container->register(LuckyController::class) - ->addTag('controller.service_arguments') - ->setBindings([ - '$logger' => new Reference('monolog.logger.doctrine'), - '$projectDir' => '%kernel.project_dir%', - ]) - ; - -Like with all services, you can also use regular :ref:`constructor injection ` -in your controllers. - -For more information about services, see the :doc:`/service_container` article. - -Autowire Parameter Attribute -~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - -.. versionadded:: 6.1 +.. tip:: - The ``#[Autowire]`` attribute was introduced in Symfony 6.1. + If you need control over the *exact* value of an argument, you can use the + ``#[Autowire]`` attribute:: -Services that cannot be autowired, :ref:`parameters ` and even -:doc:`complex expressions ` can be bound -to a controller argument with the ``#[Autowire]`` attribute:: + // ... + use Psr\Log\LoggerInterface; + use Symfony\Component\DependencyInjection\Attribute\Autowire; + use Symfony\Component\HttpFoundation\Response; - use Psr\Log\LoggerInterface; - use Symfony\Component\DependencyInjection\Attribute\Autowire; - use Symfony\Component\HttpFoundation\Response; - // ... + class LuckyController extends AbstractController + { + public function number( + int $max, + + // inject a specific logger service + #[Autowire('@monolog.logger.request')] + LoggerInterface $logger, + + // or inject parameter values + #[Autowire('%kernel.project_dir%')] + string $projectDir + ): Response + { + $logger->info('We are logging!'); + // ... + } + } - /** - * @Route("/lucky/number/{max}") - */ - public function number( - int $max, + You can read more about this attribute in :ref:`autowire-attribute`. - #[Autowire('@monolog.logger.request')] - LoggerInterface $logger, + .. versionadded:: 6.1 - #[Autowire('%kernel.project_dir%/data')] - string $dataDir, + The ``#[Autowire]`` attribute was introduced in Symfony 6.1. - #[Autowire('%kernel.debug%')] - bool $debugMode, +Like with all services, you can also use regular +:ref:`constructor injection ` in your +controllers. - #[Autowire("@=service("App\\Mail\\MailerConfiguration").getMailerMethod()")] - string $mailerMethod, - ): Response - { - $logger->info('We are logging!'); - // ... - } +For more information about services, see the :doc:`/service_container` article. Generating Controllers ---------------------- diff --git a/service_container.rst b/service_container.rst index 4e613c90708..6b6015a02e8 100644 --- a/service_container.rst +++ b/service_container.rst @@ -687,56 +687,6 @@ For a full list of *all* possible services in the container, run: .. _services-binding: -Autowire Parameter Attribute ----------------------------- - -.. versionadded:: 6.1 - - The ``#[Autowire]`` attribute was introduced in Symfony 6.1. - -For services that cannot be autowired, you can use the ``#[Autowire]`` parameter -attribute to explicitly configure the service:: - - // src/Service/MessageGenerator.php - namespace App\Service; - - use Psr\Log\LoggerInterface; - use Symfony\Component\DependencyInjection\Attribute\Autowire; - - class MessageGenerator - { - public function __construct( - #[Autowire('@monolog.logger.request')] private LoggerInterface $logger - ) { - } - // ... - } - -The ``#[Autowire]`` can also be used for :ref:`parameters ` and even -:doc:`complex expressions `:: - - // src/Service/MessageGenerator.php - namespace App\Service; - - use Psr\Log\LoggerInterface; - use Symfony\Component\DependencyInjection\Attribute\Autowire; - - class MessageGenerator - { - public function __construct( - #[Autowire('%kernel.project_dir%/data')] - private string $dataDir, - - #[Autowire('%kernel.debug%')] - private bool $debugMode, - - #[Autowire("@=service("App\\Mail\\MailerConfiguration").getMailerMethod()")] - private string $mailerMethod, - ) { - } - // ... - } - Binding Arguments by Name or Type --------------------------------- diff --git a/service_container/autowiring.rst b/service_container/autowiring.rst index 7aa968a22e4..b5387415614 100644 --- a/service_container/autowiring.rst +++ b/service_container/autowiring.rst @@ -532,6 +532,8 @@ If the argument is named ``$shoutyTransformer``, But, you can also manually wire any *other* service by specifying the argument under the arguments key. +.. _autowire-attribute: + Fixing Non-Autowireable Arguments --------------------------------- @@ -539,8 +541,58 @@ Autowiring only works when your argument is an *object*. But if you have a scala argument (e.g. a string), this cannot be autowired: Symfony will throw a clear exception. -To fix this, you can :ref:`manually wire the problematic argument `. -You wire up the difficult arguments, Symfony takes care of the rest. +To fix this, you can :ref:`manually wire the problematic argument ` +in the service configuration. You wire up only the difficult arguments, +Symfony takes care of the rest. + +You can also use the ``#[Autowire]`` parameter attribute to configure the +problematic arguments: + + // src/Service/MessageGenerator.php + namespace App\Service; + + use Psr\Log\LoggerInterface; + use Symfony\Component\DependencyInjection\Attribute\Autowire; + + class MessageGenerator + { + public function __construct( + #[Autowire('@monolog.logger.request')] LoggerInterface $logger + ) { + // ... + } + } + +.. versionadded:: 6.1 + + The ``#[Autowire]`` attribute was introduced in Symfony 6.1. + +The ``#[Autowire]`` attribute can also be used for :ref:`parameters ` +and even :doc:`complex expressions `:: + + // src/Service/MessageGenerator.php + namespace App\Service; + + use Psr\Log\LoggerInterface; + use Symfony\Component\DependencyInjection\Attribute\Autowire; + + class MessageGenerator + { + public function __construct( + // use the %...% syntax for parameters + #[Autowire('%kernel.project_dir%/data')] + string $dataDir, + + #[Autowire('%kernel.debug%')] + bool $debugMode, + + // and @=... for expressions + #[Autowire("@=service("App\\Mail\\MailerConfiguration").getMailerMethod()")] + string $mailerMethod + ) { + } + // ... + } .. _autowiring-calls: