@@ -3,53 +3,85 @@ How to Work with Compiler Passes
33
44Compiler passes give you an opportunity to manipulate other
55:doc: `service definitions </service_container/definitions >` that have been
6- registered with the service container. You can read about how to create them in
7- the components section ":ref: `components-di-separate-compiler-passes `".
6+ registered with the service container.
87
9- Compiler passes are registered in the ``build() `` method of the application kernel::
8+ .. _kernel-as-compiler-pass :
9+
10+ If your compiler pass is relatively small, you can define it inside the
11+ application's ``Kernel `` class instead of creating a
12+ :ref: `separate compiler pass class <components-di-separate-compiler-passes >`.
13+
14+ To do so, make your kernel implement :class: `Symfony\\ Component\\ DependencyInjection\\ Compiler\\ CompilerPassInterface `
15+ and add the compiler pass code inside the ``process() `` method::
1016
1117 // src/Kernel.php
1218 namespace App;
1319
14- use App\DependencyInjection\Compiler\CustomPass;
1520 use Symfony\Bundle\FrameworkBundle\Kernel\MicroKernelTrait;
21+ use Symfony\Component\DependencyInjection\Compiler\CompilerPassInterface;
1622 use Symfony\Component\DependencyInjection\ContainerBuilder;
1723 use Symfony\Component\HttpKernel\Kernel as BaseKernel;
1824
19- class Kernel extends BaseKernel
25+ class Kernel extends BaseKernel implements CompilerPassInterface
2026 {
2127 use MicroKernelTrait;
2228
2329 // ...
2430
25- protected function build (ContainerBuilder $container): void
31+ public function process (ContainerBuilder $container): void
2632 {
27- $container->addCompilerPass(new CustomPass());
33+ // in this method you can manipulate the service container:
34+ // for example, changing some container service:
35+ $container->getDefinition('app.some_private_service')->setPublic(true);
36+
37+ // or processing tagged services:
38+ foreach ($container->findTaggedServiceIds('some_tag') as $id => $tags) {
39+ // ...
40+ }
2841 }
2942 }
3043
31- .. _kernel-as-compiler-pass :
32-
33- One of the most common use-cases of compiler passes is to work with :doc: `tagged
34- services </service_container/tags>`. In those cases, instead of creating a
35- compiler pass, you can make the kernel implement
36- :class: `Symfony\\ Component\\ DependencyInjection\\ Compiler\\ CompilerPassInterface `
37- and process the services inside the ``process() `` method::
44+ If you create separate compiler pass classes, enable them in the ``build() ``
45+ method of the application kernel::
3846
3947 // src/Kernel.php
4048 namespace App;
4149
50+ use App\DependencyInjection\Compiler\CustomPass;
4251 use Symfony\Bundle\FrameworkBundle\Kernel\MicroKernelTrait;
43- use Symfony\Component\DependencyInjection\Compiler\CompilerPassInterface;
4452 use Symfony\Component\DependencyInjection\ContainerBuilder;
4553 use Symfony\Component\HttpKernel\Kernel as BaseKernel;
4654
47- class Kernel extends BaseKernel implements CompilerPassInterface
55+ class Kernel extends BaseKernel
4856 {
4957 use MicroKernelTrait;
5058
5159 // ...
5260
61+ protected function build(ContainerBuilder $container): void
62+ {
63+ $container->addCompilerPass(new CustomPass());
64+ }
65+ }
66+
67+ Working with Compiler Passes in Bundles
68+ ---------------------------------------
69+
70+ If your compiler pass is relatively small, you can add it directly in the main
71+ bundle class. To do so, make your bundle implement the
72+ :class: `Symfony\\ Component\\ DependencyInjection\\ Compiler\\ CompilerPassInterface `
73+ and place the compiler pass code inside the ``process() `` method of the main
74+ bundle class::
75+
76+ // src/MyBundle/MyBundle.php
77+ namespace App\MyBundle;
78+
79+ use App\DependencyInjection\Compiler\CustomPass;
80+ use Symfony\Component\DependencyInjection\ContainerBuilder;
81+ use Symfony\Component\HttpKernel\Bundle\AbstractBundle;
82+
83+ class MyBundle extends AbstractBundle
84+ {
5385 public function process(ContainerBuilder $container): void
5486 {
5587 // in this method you can manipulate the service container:
@@ -63,12 +95,8 @@ and process the services inside the ``process()`` method::
6395 }
6496 }
6597
66- Working with Compiler Passes in Bundles
67- ---------------------------------------
68-
69- :doc: `Bundles </bundles >` can define compiler passes in the ``build() `` method of
70- the main bundle class (this is not needed when implementing the ``process() ``
71- method in the extension)::
98+ Alternatively, when using :ref: `separate compiler pass classes <components-di-separate-compiler-passes >`,
99+ bundles can enable them in the ``build() `` method of their main bundle class::
72100
73101 // src/MyBundle/MyBundle.php
74102 namespace App\MyBundle;
@@ -88,7 +116,7 @@ method in the extension)::
88116 }
89117
90118If you are using custom :doc: `service tags </service_container/tags >` in a
91- bundle then by convention, tag names consist of the name of the bundle
92- ( lowercase, underscores as separators), followed by a dot, and finally the
93- "real" name. For example, if you want to introduce some sort of "transport" tag
94- in your AcmeMailerBundle, you should call it ``acme_mailer.transport ``.
119+ bundle, the convention is to format tag names by starting with the bundle's name
120+ in lowercase (using underscores as separators), followed by a dot, and finally
121+ the specific tag name. For example, to introduce a "transport" tag in your
122+ AcmeMailerBundle, you would name it ``acme_mailer.transport ``.
0 commit comments