@@ -3,53 +3,85 @@ How to Work with Compiler Passes
3
3
4
4
Compiler passes give you an opportunity to manipulate other
5
5
: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.
8
7
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::
10
16
11
17
// src/Kernel.php
12
18
namespace App;
13
19
14
- use App\DependencyInjection\Compiler\CustomPass;
15
20
use Symfony\Bundle\FrameworkBundle\Kernel\MicroKernelTrait;
21
+ use Symfony\Component\DependencyInjection\Compiler\CompilerPassInterface;
16
22
use Symfony\Component\DependencyInjection\ContainerBuilder;
17
23
use Symfony\Component\HttpKernel\Kernel as BaseKernel;
18
24
19
- class Kernel extends BaseKernel
25
+ class Kernel extends BaseKernel implements CompilerPassInterface
20
26
{
21
27
use MicroKernelTrait;
22
28
23
29
// ...
24
30
25
- protected function build (ContainerBuilder $container): void
31
+ public function process (ContainerBuilder $container): void
26
32
{
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
+ }
28
41
}
29
42
}
30
43
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::
38
46
39
47
// src/Kernel.php
40
48
namespace App;
41
49
50
+ use App\DependencyInjection\Compiler\CustomPass;
42
51
use Symfony\Bundle\FrameworkBundle\Kernel\MicroKernelTrait;
43
- use Symfony\Component\DependencyInjection\Compiler\CompilerPassInterface;
44
52
use Symfony\Component\DependencyInjection\ContainerBuilder;
45
53
use Symfony\Component\HttpKernel\Kernel as BaseKernel;
46
54
47
- class Kernel extends BaseKernel implements CompilerPassInterface
55
+ class Kernel extends BaseKernel
48
56
{
49
57
use MicroKernelTrait;
50
58
51
59
// ...
52
60
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
+ {
53
85
public function process(ContainerBuilder $container): void
54
86
{
55
87
// in this method you can manipulate the service container:
@@ -63,12 +95,8 @@ and process the services inside the ``process()`` method::
63
95
}
64
96
}
65
97
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::
72
100
73
101
// src/MyBundle/MyBundle.php
74
102
namespace App\MyBundle;
@@ -88,7 +116,7 @@ method in the extension)::
88
116
}
89
117
90
118
If 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