From 2c33c3623d631fc631bf75d3a5dcfbfb3d2c259f Mon Sep 17 00:00:00 2001 From: Javier Eguiluz Date: Fri, 23 May 2025 09:12:33 +0200 Subject: [PATCH] [FrameworkBundle] Enable controller service with #[Route] attribute --- controller/service.rst | 84 +++++++++++++++++++++++++++++------------- routing.rst | 2 + 2 files changed, 61 insertions(+), 25 deletions(-) diff --git a/controller/service.rst b/controller/service.rst index 88af093ff29..cf83e066a19 100644 --- a/controller/service.rst +++ b/controller/service.rst @@ -7,11 +7,65 @@ and your controllers extend the `AbstractController`_ class, they *are* automati registered as services. This means you can use dependency injection like any other normal service. -If your controllers don't extend the `AbstractController`_ class, you must -explicitly mark your controller services as ``public``. Alternatively, you can -apply the ``controller.service_arguments`` tag to your controller services. This -will make the tagged services ``public`` and will allow you to inject services -in method parameters: +If you prefer to not extend the ``AbstractController`` class, you can register +your controllers as services in several ways: + +#. Using the ``#[Route]`` attribute; +#. Using the ``#[AsController]`` attribute; +#. Using the ``controller.service_arguments`` service tag. + +Using the ``#[Route]`` Attribute +-------------------------------- + +When using :ref:`the #[Route] attribute ` to define +routes on any PHP class, Symfony treats that class as a controller. It registers +it as a public, non-lazy service and enables service argument injection in all +its methods. + +This is the simplest and recommended way to register controllers as services +when not extending the base controller class. + +.. versionadded:: 7.3 + + The feature to register controllers as services when using the ``#[Route]`` + attribute was introduced in Symfony 7.3. + +Using the ``#[AsController]`` Attribute +--------------------------------------- + +If you prefer, you can use the ``#[AsController]`` PHP attribute to automatically +apply the ``controller.service_arguments`` tag to your controller services:: + + // src/Controller/HelloController.php + namespace App\Controller; + + use Symfony\Component\HttpFoundation\Response; + use Symfony\Component\HttpKernel\Attribute\AsController; + use Symfony\Component\Routing\Attribute\Route; + + #[AsController] + class HelloController + { + #[Route('/hello', name: 'hello', methods: ['GET'])] + public function index(): Response + { + // ... + } + } + +.. tip:: + + When using the ``#[Route]`` attribute, Symfony already registers the controller + class as a service, so using the ``#[AsController]`` attribute is redundant. + +Using the ``controller.service_arguments`` Service Tag +------------------------------------------------------ + +If your controllers don't extend the `AbstractController`_ class and you don't +use the ``#[AsController]`` or ``#[Route]`` attributes, you must register the +controllers as public services manually and apply the ``controller.service_arguments`` +:doc:`service tag ` to enable service injection in +controller actions: .. configuration-block:: @@ -58,26 +112,6 @@ in method parameters: calls: - [setContainer, ['@abstract_controller.locator']] -If you prefer, you can use the ``#[AsController]`` PHP attribute to automatically -apply the ``controller.service_arguments`` tag to your controller services:: - - // src/Controller/HelloController.php - namespace App\Controller; - - use Symfony\Component\HttpFoundation\Response; - use Symfony\Component\HttpKernel\Attribute\AsController; - use Symfony\Component\Routing\Attribute\Route; - - #[AsController] - class HelloController - { - #[Route('/hello', name: 'hello', methods: ['GET'])] - public function index(): Response - { - // ... - } - } - Registering your controller as a service is the first step, but you also need to update your routing config to reference the service properly, so that Symfony knows to use it. diff --git a/routing.rst b/routing.rst index e634a410c37..b8b2437ee3e 100644 --- a/routing.rst +++ b/routing.rst @@ -18,6 +18,8 @@ your favorite. :ref:`Symfony recommends attributes ` because it's convenient to put the route and controller in the same place. +.. _routing-route-attributes: + Creating Routes as Attributes ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~