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,39 +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- Symfony creates a big ``classes.php `` file in the cache directory to aggregate
133- the contents of the PHP classes that are used in every request. This reduces the
134- I/O operations and increases the application performance.
135-
136- Your bundles can also add their own classes into this file thanks to the
137- ``addClassesToCompile() `` and ``addAnnotatedClassesToCompile() `` methods (both
138- work in the same way, but the second one is for classes that contain PHP
139- annotations). Define the classes to compile as an array of their fully qualified
140- 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::
141120
142121 use App\Manager\UserManager;
143122 use App\Utils\Slugger;
@@ -147,16 +126,12 @@ class names::
147126 {
148127 // ...
149128
150- // this method can't compile classes that contain PHP annotations
151- $this->addClassesToCompile(array(
152- UserManager::class,
153- Slugger::class,
154- // ...
155- ));
156-
157- // add here only classes that contain PHP annotations
158129 $this->addAnnotatedClassesToCompile(array(
130+ // you can define the fully qualified class names...
159131 'App\\Controller\\DefaultController',
132+ // ... but glob patterns are also supported:
133+ '**Bundle\\Controller\\',
134+
160135 // ...
161136 ));
162137 }
@@ -166,24 +141,6 @@ class names::
166141 If some class extends from other classes, all its parents are automatically
167142 included in the list of classes to compile.
168143
169- The classes to compile can also be added using file path patterns::
170-
171- // ...
172- public function load(array $configs, ContainerBuilder $container)
173- {
174- // ...
175-
176- $this->addClassesToCompile(array(
177- '**Bundle\\Manager\\',
178- // ...
179- ));
180-
181- $this->addAnnotatedClassesToCompile(array(
182- '**Bundle\\Controller\\',
183- // ...
184- ));
185- }
186-
187144Patterns are transformed into the actual class namespaces using the classmap
188145generated by Composer. Therefore, before using these patterns, you must generate
189146the full classmap executing the ``dump-autoload `` command of Composer.