@@ -128,17 +128,298 @@ a relative or absolute path to the imported file:
128128 $services->load('App\\', '../src/*');
129129 };
130130
131- When loading a configuration file, Symfony loads first the imported files and
132- then it processes the parameters and services defined in the file. If you use the
133- :ref: `default services.yaml configuration <service-container-services-load-example >`
134- as in the above example, the ``App\ `` definition creates services for classes
135- found in ``../src/* ``. If your imported file defines services for those classes
136- too, they will be overridden.
137-
138- A possible solution for this is to add the classes and/or directories of the
139- imported files in the ``exclude `` option of the ``App\ `` definition. Another
140- solution is to not use imports and add the service definitions in the same file,
141- but after the ``App\ `` definition to override it.
131+ When loading a configuration file, Symfony first processes all imported files in
132+ the order they are listed under the ``imports `` key. After all imports are processed,
133+ it then processes the parameters and services defined directly in the current file.
134+ In practice, this means that **later definitions override earlier ones **.
135+
136+ For example, if you use the :ref: `default services.yaml configuration <service-container-services-load-example >`
137+ as in the above example, your main ``config/services.yaml `` file uses the ``App\ ``
138+ namespace to auto-discover services and loads them after all imported files.
139+ If an imported file (e.g. ``config/services/mailer.yaml ``) defines a service that
140+ is also auto-discovered, the definition from ``services.yaml `` will take precedence.
141+
142+ To make sure your specific service definitions are not overridden by auto-discovery,
143+ consider one of the following strategies:
144+
145+ #. :ref: `Exclude services from auto-discovery <import-exclude-services-from-auto-discovery >`
146+ #. :ref: `Override services in the same file <import-override-services-in-the-same-file >`
147+ #. :ref: `Control import order <import-control-import-order >`
148+
149+ .. _import-exclude-services-from-auto-discovery :
150+
151+ **Exclude services from auto-discovery **
152+
153+ Adjust the ``App\ `` definition to use the ``exclude `` option. This prevents Symfony
154+ from auto-registering classes that are defined manually elsewhere:
155+
156+ .. configuration-block ::
157+
158+ .. code-block :: yaml
159+
160+ # config/services.yaml
161+ imports :
162+ - { resource: services/mailer.yaml }
163+ # ... other imports
164+
165+ services :
166+ _defaults :
167+ autowire : true
168+ autoconfigure : true
169+
170+ App\ :
171+ resource : ' ../src/*'
172+ exclude :
173+ - ' ../src/Mailer/'
174+ - ' ../src/SpecificClass.php'
175+
176+ .. code-block: : xml
177+
178+ <!-- config/services.xml -->
179+ <?xml version="1.0" encoding="UTF-8" ?>
180+ <container xmlns="http://symfony.com/schema/dic/services"
181+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
182+ xsi:schemaLocation="http://symfony.com/schema/dic/services
183+ https://symfony.com/schema/dic/services/services-1.0.xsd">
184+
185+ <imports>
186+ <import resource="services/mailer.xml"/>
187+ <!-- If you want to import a whole directory : -->
188+ <import resource="services/"/>
189+ </imports>
190+
191+ <services>
192+ <defaults autowire="true" autoconfigure="true"/>
193+
194+ <prototype namespace="App\" resource="../src/*">
195+ <exclude>../src/Mailer/</exclude>
196+ <exclude>../src/SpecificClass.php</exclude>
197+ </prototype>
198+
199+ <!-- ... -->
200+ </services>
201+ </container>
202+
203+ .. code-block: : php
204+
205+ // config/services.php
206+ namespace Symfony\Component\DependencyInjection\Loader\Configurator;
207+
208+ return function(ContainerConfigurator $container) : void {
209+ $container->import('services/mailer.php');
210+ // If you want to import a whole directory :
211+ $container->import('services/');
212+
213+ $services = $container->services()
214+ ->defaults()
215+ ->autowire()
216+ ->autoconfigure()
217+ ;
218+
219+ $services->load('App\\', '../src/*')
220+ ->exclude([
221+ ' ../src/Mailer/' ,
222+ ' ../src/SpecificClass.php' ,
223+ ]);
224+ };
225+
226+ .. _import-override-services-in-the-same-file :
227+
228+ **Override services in the same file **
229+
230+ You can define specific services after the ``App\ `` auto-discovery block in the
231+ same file. These later definitions will override the auto-registered ones:
232+
233+ .. configuration-block ::
234+
235+ .. code-block :: yaml
236+
237+ # config/services.yaml
238+ services :
239+ _defaults :
240+ autowire : true
241+ autoconfigure : true
242+
243+ App\ :
244+ resource : ' ../src/*'
245+
246+ App\Mailer\MyMailer :
247+ arguments : ['%env(MAILER_DSN)%']
248+
249+ .. code-block: : xml
250+
251+ <!-- config/services.xml -->
252+ <?xml version="1.0" encoding="UTF-8" ?>
253+ <container xmlns="http://symfony.com/schema/dic/services"
254+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
255+ xsi:schemaLocation="http://symfony.com/schema/dic/services
256+ https://symfony.com/schema/dic/services/services-1.0.xsd">
257+
258+ <imports>
259+ <import resource="services/mailer.xml"/>
260+ <!-- If you want to import a whole directory : -->
261+ <import resource="services/"/>
262+ </imports>
263+
264+ <services>
265+ <defaults autowire="true" autoconfigure="true"/>
266+
267+ <prototype namespace="App\" resource="../src/*"/>
268+
269+ <service id="App\Mailer\MyMailer">
270+ <argument>%env(MAILER_DSN)%</argument>
271+ </service>
272+
273+ <!-- ... -->
274+ </services>
275+ </container>
276+
277+ .. code-block: : php
278+
279+ // config/services.php
280+ namespace Symfony\Component\DependencyInjection\Loader\Configurator;
281+
282+ return function(ContainerConfigurator $container) : void {
283+ $services = $container->services()
284+ ->defaults()
285+ ->autowire()
286+ ->autoconfigure();
287+
288+ $services->load('App\\', '../src/*');
289+
290+ $services->set(App\Mailer\MyMailer::class)
291+ ->arg(0, '%env(MAILER_DSN)%');
292+ };
293+
294+ .. _import-control-import-order :
295+
296+ **Control import order **
297+
298+ Move the ``App\ `` auto-discovery config to a separate file and import it
299+ before more specific service files. This way, specific service definitions
300+ can override the auto-discovered ones.
301+
302+ .. configuration-block ::
303+
304+ .. code-block :: yaml
305+
306+ # config/services/autodiscovery.yaml
307+ services :
308+ _defaults :
309+ autowire : true
310+ autoconfigure : true
311+
312+ App\ :
313+ resource : ' ../../src/*'
314+ exclude :
315+ - ' ../../src/Mailer/'
316+
317+ # config/services/mailer.yaml
318+ services :
319+ App\Mailer\SpecificMailer :
320+ # ... custom configuration
321+
322+ # config/services.yaml
323+ imports :
324+ - { resource: services/autodiscovery.yaml }
325+ - { resource: services/mailer.yaml }
326+ - { resource: services/ }
327+
328+ services :
329+ # definitions here override anything from the imports above
330+ # consider keeping most definitions inside imported files
331+
332+ .. code-block :: xml
333+
334+ <!-- config/services/autodiscovery.xml -->
335+ <?xml version =" 1.0" encoding =" UTF-8" ?>
336+ <container xmlns =" http://symfony.com/schema/dic/services"
337+ xmlns : xsi =" http://www.w3.org/2001/XMLSchema-instance"
338+ xsi : schemaLocation =" http://symfony.com/schema/dic/services
339+ https://symfony.com/schema/dic/services/services-1.0.xsd" >
340+
341+ <services >
342+ <defaults autowire =" true" autoconfigure =" true" />
343+
344+ <prototype namespace =" App\" resource =" ../../src/*" >
345+ <exclude >../../src/Mailer/</exclude >
346+ </prototype >
347+ </services >
348+ </container >
349+
350+ <!-- config/services/mailer.xml -->
351+ <?xml version =" 1.0" encoding =" UTF-8" ?>
352+ <container xmlns =" http://symfony.com/schema/dic/services"
353+ xmlns : xsi =" http://www.w3.org/2001/XMLSchema-instance"
354+ xsi : schemaLocation =" http://symfony.com/schema/dic/services
355+ https://symfony.com/schema/dic/services/services-1.0.xsd" >
356+
357+ <services >
358+ <service id =" App\Mailer\SpecificMailer" >
359+ <!-- ... custom configuration -->
360+ </service >
361+ </services >
362+ </container >
363+
364+ <!-- config/services.xml -->
365+ <?xml version =" 1.0" encoding =" UTF-8" ?>
366+ <container xmlns =" http://symfony.com/schema/dic/services"
367+ xmlns : xsi =" http://www.w3.org/2001/XMLSchema-instance"
368+ xsi : schemaLocation =" http://symfony.com/schema/dic/services
369+ https://symfony.com/schema/dic/services/services-1.0.xsd" >
370+
371+ <imports >
372+ <import resource =" services/autodiscovery.xml" />
373+ <import resource =" services/mailer.xml" />
374+ <import resource =" services/" />
375+ </imports >
376+
377+ <services >
378+ <!-- definitions here override anything from the imports above -->
379+ <!-- consider keeping most definitions inside imported files -->
380+ </services >
381+ </container >
382+
383+ .. code-block :: php
384+
385+ // config/services/autodiscovery.php
386+ use Symfony\Component\DependencyInjection\Loader\Configurator\ContainerConfigurator;
387+
388+ return function (ContainerConfigurator $container): void {
389+ $services = $container->services()
390+ ->defaults()
391+ ->autowire()
392+ ->autoconfigure();
393+
394+ $services->load('App\\', '../../src/*')
395+ ->exclude([
396+ '../../src/Mailer/',
397+ ]);
398+ };
399+
400+ // config/services/mailer.php
401+ use Symfony\Component\DependencyInjection\Loader\Configurator\ContainerConfigurator;
402+
403+ return function (ContainerConfigurator $container): void {
404+ $services = $container->services();
405+
406+ $services->set(App\Mailer\SpecificMailer::class);
407+ // Add any custom configuration here if needed
408+ };
409+
410+ // config/services.php
411+ use Symfony\Component\DependencyInjection\Loader\Configurator\ContainerConfigurator;
412+
413+ return function (ContainerConfigurator $container): void {
414+ $container->import('services/autodiscovery.php');
415+ $container->import('services/mailer.php');
416+ $container->import('services/');
417+
418+ $services = $container->services();
419+
420+ // definitions here override anything from the imports above
421+ // consider keeping most definitions inside imported files
422+ };
142423
143424 .. include :: /components/dependency_injection/_imports-parameters-note.rst.inc
144425
0 commit comments