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