@@ -128,17 +128,298 @@ a relative or absolute path to the imported file:
128
128
$services->load('App\\', '../src/*');
129
129
};
130
130
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
+ };
142
423
143
424
.. include :: /components/dependency_injection/_imports-parameters-note.rst.inc
144
425
0 commit comments