5
5
How to Load Service Configuration inside a Bundle
6
6
=================================================
7
7
8
- In Symfony, you'll find yourself using many services. These services can be
9
- registered in the ``app/config/ `` directory of your application. But when you
10
- want to decouple the bundle for use in other projects, you want to include the
11
- service configuration in the bundle itself. This article will teach you how to
12
- do that.
8
+ Services created by bundles are not defined in the main ``config/services.yaml ``
9
+ file used by the application but in the bundles themselves. This article
10
+ explains how to create and load those bundle services files.
13
11
14
12
Creating an Extension Class
15
13
---------------------------
16
14
17
15
In order to load service configuration, you have to create a Dependency
18
- Injection (DI) Extension for your bundle. This class has some conventions in order
19
- to be detected automatically. But you'll later see how you can change it to
20
- your own preferences. By default, the Extension has to comply with the
21
- following conventions:
16
+ Injection (DI) Extension for your bundle. By default, the Extension class must
17
+ follow these conventions (but later you'll learn how to skip them if needed):
22
18
23
19
* It has to live in the ``DependencyInjection `` namespace of the bundle;
24
20
21
+ * It has to implement the :class: `Symfony\\ Component\\ DependencyInjection\\ Extension\\ ExtensionInterface `,
22
+ which is usually achieve by extending the
23
+ :class: `Symfony\\ Component\\ DependencyInjection\\ Extension\\ Extension ` class;
24
+
25
25
* The name is equal to the bundle name with the ``Bundle `` suffix replaced by
26
- ``Extension `` (e.g. the Extension class of the AppBundle would be called
27
- ``AppExtension `` and the one for AcmeHelloBundle would be called
26
+ ``Extension `` (e.g. the Extension class of the AcmeBundle would be called
27
+ ``AcmeExtension `` and the one for AcmeHelloBundle would be called
28
28
``AcmeHelloExtension ``).
29
29
30
- The Extension class should implement the
31
- :class: `Symfony\\ Component\\ DependencyInjection\\ Extension\\ ExtensionInterface `,
32
- but usually you would simply extend the
33
- :class: `Symfony\\ Component\\ DependencyInjection\\ Extension\\ Extension ` class::
30
+ This is how the extension of an AcmeHelloBundle should look like::
34
31
35
32
// src/Acme/HelloBundle/DependencyInjection/AcmeHelloExtension.php
36
33
namespace Acme\HelloBundle\DependencyInjection;
@@ -65,11 +62,11 @@ method to return the instance of the extension::
65
62
}
66
63
}
67
64
68
- Since the new Extension class name doesn't follow the naming conventions, you
69
- should also override
65
+ In addition, when the new Extension class name doesn't follow the naming
66
+ conventions, you must also override the
70
67
:method: `Extension::getAlias() <Symfony\\ Component\\ DependencyInjection\\ Extension\\ Extension::getAlias> `
71
- to return the correct DI alias. The DI alias is the name used to refer to the
72
- bundle in the container (e.g. in the ``app/ config/config.yml `` file ). By
68
+ method to return the correct DI alias. The DI alias is the name used to refer to
69
+ the bundle in the container (e.g. in the ``config/packages/ `` files ). By
73
70
default, this is done by removing the ``Extension `` suffix and converting the
74
71
class name to underscores (e.g. ``AcmeHelloExtension ``'s DI alias is
75
72
``acme_hello ``).
@@ -86,11 +83,10 @@ container.
86
83
87
84
In the ``load() `` method, you can use PHP code to register service definitions,
88
85
but it is more common if you put these definitions in a configuration file
89
- (using the Yaml, XML or PHP format). Luckily, you can use the file loaders in
90
- the extension!
86
+ (using the YAML, XML or PHP format).
91
87
92
88
For instance, assume you have a file called ``services.xml `` in the
93
- ``Resources/config `` directory of your bundle, your ``load() `` method looks like::
89
+ ``Resources/config/ `` directory of your bundle, your ``load() `` method looks like::
94
90
95
91
use Symfony\Component\DependencyInjection\Loader\XmlFileLoader;
96
92
use Symfony\Component\Config\FileLocator;
@@ -105,46 +101,22 @@ For instance, assume you have a file called ``services.xml`` in the
105
101
$loader->load('services.xml');
106
102
}
107
103
108
- Other available loaders are the ``YamlFileLoader ``, ``PhpFileLoader `` and
109
- ``IniFileLoader ``.
110
-
111
- .. note ::
112
-
113
- The ``IniFileLoader `` can only be used to load parameters and it can only
114
- load them as strings.
115
-
116
- .. caution ::
117
-
118
- If you removed the default file with service definitions (i.e.
119
- ``config/services.yaml ``), make sure to also remove it from the
120
- ``imports `` key in ``app/config/config.yml ``.
104
+ The other available loaders are ``YamlFileLoader `` and ``PhpFileLoader ``.
121
105
122
106
Using Configuration to Change the Services
123
107
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
124
108
125
109
The Extension is also the class that handles the configuration for that
126
- particular bundle (e.g. the configuration in ``app/ config/config.yml ``). To
127
- read more about it, see the ":doc: `/bundles/configuration `" article.
110
+ particular bundle (e.g. the configuration in ``config/packages/<bundle_alias>.yaml ``).
111
+ To read more about it, see the ":doc: `/bundles/configuration `" article.
128
112
129
113
Adding Classes to Compile
130
114
-------------------------
131
115
132
- .. versionadded :: 3.3
133
- This technique is discouraged and the ``addClassesToCompile() `` method was
134
- deprecated in Symfony 3.3 because modern PHP versions make it unnecessary.
135
-
136
- Symfony creates a big ``classes.php `` file in the cache directory to aggregate
137
- the contents of the PHP classes that are used in every request. This reduces the
138
- I/O operations and increases the application performance.
139
-
140
- .. versionadded :: 3.2
141
- The ``addAnnotatedClassesToCompile() `` method was added in Symfony 3.2.
142
-
143
- Your bundles can also add their own classes into this file thanks to the
144
- ``addClassesToCompile() `` and ``addAnnotatedClassesToCompile() `` methods (both
145
- work in the same way, but the second one is for classes that contain PHP
146
- annotations). Define the classes to compile as an array of their fully qualified
147
- class names::
116
+ Bundles can hint Symfony about which of their classes contain annotations so
117
+ they are compiled when generating the application cache to improve the overall
118
+ performance. Define the list of annotated classes to compile in the
119
+ ``addAnnotatedClassesToCompile() `` method::
148
120
149
121
use App\Manager\UserManager;
150
122
use App\Utils\Slugger;
@@ -154,16 +126,12 @@ class names::
154
126
{
155
127
// ...
156
128
157
- // this method can't compile classes that contain PHP annotations
158
- $this->addClassesToCompile(array(
159
- UserManager::class,
160
- Slugger::class,
161
- // ...
162
- ));
163
-
164
- // add here only classes that contain PHP annotations
165
129
$this->addAnnotatedClassesToCompile(array(
130
+ // you can define the fully qualified class names...
166
131
'App\\Controller\\DefaultController',
132
+ // ... but glob patterns are also supported:
133
+ '**Bundle\\Controller\\',
134
+
167
135
// ...
168
136
));
169
137
}
@@ -173,27 +141,6 @@ class names::
173
141
If some class extends from other classes, all its parents are automatically
174
142
included in the list of classes to compile.
175
143
176
- .. versionadded :: 3.2
177
- The option to add classes to compile using patterns was introduced in Symfony 3.2.
178
-
179
- The classes to compile can also be added using file path patterns::
180
-
181
- // ...
182
- public function load(array $configs, ContainerBuilder $container)
183
- {
184
- // ...
185
-
186
- $this->addClassesToCompile(array(
187
- '**Bundle\\Manager\\',
188
- // ...
189
- ));
190
-
191
- $this->addAnnotatedClassesToCompile(array(
192
- '**Bundle\\Controller\\',
193
- // ...
194
- ));
195
- }
196
-
197
144
Patterns are transformed into the actual class namespaces using the classmap
198
145
generated by Composer. Therefore, before using these patterns, you must generate
199
146
the full classmap executing the ``dump-autoload `` command of Composer.
0 commit comments