@@ -246,9 +246,80 @@ service type to a service.
246
246
Defining a Service Locator
247
247
--------------------------
248
248
249
- To manually define a service locator, create a new service definition and add
250
- the ``container.service_locator `` tag to it. Use the first argument of the
251
- service definition to pass a collection of services to the service locator:
249
+ To manually define a service locator and inject it to another service, create an
250
+ argument of type ``service_locator ``:
251
+
252
+ .. configuration-block ::
253
+
254
+ .. code-block :: yaml
255
+
256
+ # config/services.yaml
257
+ services :
258
+ App\CommandBus :
259
+ arguments :
260
+ !service_locator
261
+ App\FooCommand : ' @app.command_handler.foo'
262
+ App\BarCommand : ' @app.command_handler.bar'
263
+
264
+ .. code-block :: xml
265
+
266
+ <!-- config/services.xml -->
267
+ <?xml version =" 1.0" encoding =" UTF-8" ?>
268
+ <container xmlns =" http://symfony.com/schema/dic/services"
269
+ xmlns : xsi =" http://www.w3.org/2001/XMLSchema-instance"
270
+ xsi : schemaLocation =" http://symfony.com/schema/dic/services https://symfony.com/schema/dic/services/services-1.0.xsd" >
271
+
272
+ <services >
273
+ <service id =" App\CommandBus" >
274
+ <argument type =" service_locator" >
275
+ <argument key =" App\FooCommand" type =" service" id =" sapp.command_handler.foo" />
276
+ <argument key =" App\BarCommandr" type =" service" id =" app.command_handler.bar" />
277
+ <!-- if the element has no key, the ID of the original service is used -->
278
+ <argument type =" service" id =" app.command_handler.baz" />
279
+ </argument >
280
+ </service >
281
+ </services >
282
+ </container >
283
+
284
+ .. code-block :: php
285
+
286
+ // config/services.php
287
+ namespace Symfony\Component\DependencyInjection\Loader\Configurator;
288
+
289
+ use App\CommandBus;
290
+
291
+ return function(ContainerConfigurator $configurator) {
292
+ $services = $configurator->services();
293
+
294
+ $services->set(CommandBus::class)
295
+ ->args([service_locator([
296
+ 'App\FooCommand' => ref('app.command_handler.foo'),
297
+ 'App\BarCommand' => ref('app.command_handler.bar'),
298
+ // if the element has no key, the ID of the original service is used
299
+ ref('app.command_handler.baz'),
300
+ ])]);
301
+ };
302
+
303
+ .. versionadded :: 4.2
304
+
305
+ The ability to add services without specifying an array key was introduced
306
+ in Symfony 4.2.
307
+
308
+ .. versionadded :: 4.2
309
+
310
+ The ``service_locator `` argument type was introduced in Symfony 4.2.
311
+
312
+ As shown in the previous sections, the constructor of the ``CommandBus `` class
313
+ must type-hint its argument with ``ContainerInterface ``. Then, you can get any of
314
+ the service locator services via their ID (e.g. ``$this->locator->get('App\FooCommand') ``).
315
+
316
+ Reusing a Service Locator in Multiple Services
317
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
318
+
319
+ If you inject the same service locator in several services, it's better to
320
+ define the service locator as a stand-alone service and then inject it in the
321
+ other services. To do so, create a new service definition using the
322
+ ``ServiceLocator `` class:
252
323
253
324
.. configuration-block ::
254
325
@@ -334,7 +405,7 @@ service definition to pass a collection of services to the service locator:
334
405
The services defined in the service locator argument must include keys,
335
406
which later become their unique identifiers inside the locator.
336
407
337
- Now you can use the service locator by injecting it in any other service :
408
+ Now you can inject the service locator in any other services :
338
409
339
410
.. configuration-block ::
340
411
@@ -376,6 +447,9 @@ Now you can use the service locator by injecting it in any other service:
376
447
->args([service('app.command_handler_locator')]);
377
448
};
378
449
450
+ Using Service Locators in Compiler Passes
451
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
452
+
379
453
In :doc: `compiler passes </service_container/compiler_passes >` it's recommended
380
454
to use the :method: `Symfony\\ Component\\ DependencyInjection\\ Compiler\\ ServiceLocatorTagPass::register `
381
455
method to create the service locators. This will save you some boilerplate and
0 commit comments