55How to Load Service Configuration inside a Bundle
66=================================================
77
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.
1311
1412Creating an Extension Class
1513---------------------------
1614
1715In 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):
2218
2319* It has to live in the ``DependencyInjection `` namespace of the bundle;
2420
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+
2525* The name is equal to the bundle name with the ``Bundle `` suffix replaced by
26- ``Extension `` (e.g. the Extension class of theAppBundle would be called
27- ``AppExtension `` and the one for AcmeHelloBundle would be called
26+ ``Extension `` (e.g. the Extension class of theAcmeBundle would be called
27+ ``AcmeExtension `` and the one for AcmeHelloBundle would be called
2828 ``AcmeHelloExtension ``).
2929
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::
3431
3532 // src/Acme/HelloBundle/DependencyInjection/AcmeHelloExtension.php
3633 namespace Acme\HelloBundle\DependencyInjection;
@@ -65,11 +62,11 @@ method to return the instance of the extension::
6562 }
6663 }
6764
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
7067: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
7370default, this is done by removing the ``Extension `` suffix and converting the
7471class name to underscores (e.g. ``AcmeHelloExtension ``'s DI alias is
7572``acme_hello ``).
@@ -86,11 +83,10 @@ container.
8683
8784In the ``load() `` method, you can use PHP code to register service definitions,
8885but 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).
9187
9288For 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::
9490
9591 use Symfony\Component\DependencyInjection\Loader\XmlFileLoader;
9692 use Symfony\Component\Config\FileLocator;
@@ -105,46 +101,22 @@ For instance, assume you have a file called ``services.xml`` in the
105101 $loader->load('services.xml');
106102 }
107103
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 ``.
121105
122106Using Configuration to Change the Services
123107~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
124108
125109The 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.
128112
129113Adding Classes to Compile
130114-------------------------
131115
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::
148120
149121 use App\Manager\UserManager;
150122 use App\Utils\Slugger;
@@ -154,16 +126,12 @@ class names::
154126 {
155127 // ...
156128
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
165129 $this->addAnnotatedClassesToCompile(array(
130+ // you can define the fully qualified class names...
166131 'App\\Controller\\DefaultController',
132+ // ... but glob patterns are also supported:
133+ '**Bundle\\Controller\\',
134+
167135 // ...
168136 ));
169137 }
@@ -173,27 +141,6 @@ class names::
173141 If some class extends from other classes, all its parents are automatically
174142 included in the list of classes to compile.
175143
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-
197144Patterns are transformed into the actual class namespaces using the classmap
198145generated by Composer. Therefore, before using these patterns, you must generate
199146the full classmap executing the ``dump-autoload `` command of Composer.