diff --git a/service_container/compiler_passes.rst b/service_container/compiler_passes.rst index fc5728685e0..11458a4e8e3 100644 --- a/service_container/compiler_passes.rst +++ b/service_container/compiler_passes.rst @@ -3,53 +3,85 @@ How to Work with Compiler Passes Compiler passes give you an opportunity to manipulate other :doc:`service definitions ` that have been -registered with the service container. You can read about how to create them in -the components section ":ref:`components-di-separate-compiler-passes`". +registered with the service container. -Compiler passes are registered in the ``build()`` method of the application kernel:: +.. _kernel-as-compiler-pass: + +If your compiler pass is relatively small, you can define it inside the +application's ``Kernel`` class instead of creating a +:ref:`separate compiler pass class `. + +To do so, make your kernel implement :class:`Symfony\\Component\\DependencyInjection\\Compiler\\CompilerPassInterface` +and add the compiler pass code inside the ``process()`` method:: // src/Kernel.php namespace App; - use App\DependencyInjection\Compiler\CustomPass; use Symfony\Bundle\FrameworkBundle\Kernel\MicroKernelTrait; + use Symfony\Component\DependencyInjection\Compiler\CompilerPassInterface; use Symfony\Component\DependencyInjection\ContainerBuilder; use Symfony\Component\HttpKernel\Kernel as BaseKernel; - class Kernel extends BaseKernel + class Kernel extends BaseKernel implements CompilerPassInterface { use MicroKernelTrait; // ... - protected function build(ContainerBuilder $container): void + public function process(ContainerBuilder $container): void { - $container->addCompilerPass(new CustomPass()); + // in this method you can manipulate the service container: + // for example, changing some container service: + $container->getDefinition('app.some_private_service')->setPublic(true); + + // or processing tagged services: + foreach ($container->findTaggedServiceIds('some_tag') as $id => $tags) { + // ... + } } } -.. _kernel-as-compiler-pass: - -One of the most common use-cases of compiler passes is to work with :doc:`tagged -services `. In those cases, instead of creating a -compiler pass, you can make the kernel implement -:class:`Symfony\\Component\\DependencyInjection\\Compiler\\CompilerPassInterface` -and process the services inside the ``process()`` method:: +If you create separate compiler pass classes, enable them in the ``build()`` +method of the application kernel:: // src/Kernel.php namespace App; + use App\DependencyInjection\Compiler\CustomPass; use Symfony\Bundle\FrameworkBundle\Kernel\MicroKernelTrait; - use Symfony\Component\DependencyInjection\Compiler\CompilerPassInterface; use Symfony\Component\DependencyInjection\ContainerBuilder; use Symfony\Component\HttpKernel\Kernel as BaseKernel; - class Kernel extends BaseKernel implements CompilerPassInterface + class Kernel extends BaseKernel { use MicroKernelTrait; // ... + protected function build(ContainerBuilder $container): void + { + $container->addCompilerPass(new CustomPass()); + } + } + +Working with Compiler Passes in Bundles +--------------------------------------- + +If your compiler pass is relatively small, you can add it directly in the main +bundle class. To do so, make your bundle implement the +:class:`Symfony\\Component\\DependencyInjection\\Compiler\\CompilerPassInterface` +and place the compiler pass code inside the ``process()`` method of the main +bundle class:: + + // src/MyBundle/MyBundle.php + namespace App\MyBundle; + + use App\DependencyInjection\Compiler\CustomPass; + use Symfony\Component\DependencyInjection\ContainerBuilder; + use Symfony\Component\HttpKernel\Bundle\AbstractBundle; + + class MyBundle extends AbstractBundle + { public function process(ContainerBuilder $container): void { // in this method you can manipulate the service container: @@ -63,12 +95,8 @@ and process the services inside the ``process()`` method:: } } -Working with Compiler Passes in Bundles ---------------------------------------- - -:doc:`Bundles ` can define compiler passes in the ``build()`` method of -the main bundle class (this is not needed when implementing the ``process()`` -method in the extension):: +Alternatively, when using :ref:`separate compiler pass classes `, +bundles can enable them in the ``build()`` method of their main bundle class:: // src/MyBundle/MyBundle.php namespace App\MyBundle; @@ -88,7 +116,7 @@ method in the extension):: } If you are using custom :doc:`service tags ` in a -bundle then by convention, tag names consist of the name of the bundle -(lowercase, underscores as separators), followed by a dot, and finally the -"real" name. For example, if you want to introduce some sort of "transport" tag -in your AcmeMailerBundle, you should call it ``acme_mailer.transport``. +bundle, the convention is to format tag names by starting with the bundle's name +in lowercase (using underscores as separators), followed by a dot, and finally +the specific tag name. For example, to introduce a "transport" tag in your +AcmeMailerBundle, you would name it ``acme_mailer.transport``.