@@ -246,9 +246,80 @@ service type to a service.
246246Defining a Service Locator
247247-------------------------- 
248248
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:
252323
253324.. configuration-block ::
254325
@@ -334,17 +405,7 @@ service definition to pass a collection of services to the service locator:
334405 previous Symfony versions you always needed to add the
335406 ``container.service_locator `` tag explicitly.
336407
337- .. versionadded :: 4.2 
338- 
339-  The ability to add services without specifying their id was introduced in
340-  Symfony 4.2.
341- 
342- .. note ::
343- 
344-  The services defined in the service locator argument must include keys,
345-  which later become their unique identifiers inside the locator.
346- 
347- 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:
348409
349410.. configuration-block ::
350411
@@ -386,6 +447,9 @@ Now you can use the service locator by injecting it in any other service:
386447 ->args([ref('app.command_handler_locator')]); 
387448 }; 
388449
450+ 
451+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 
452+ 
389453In :doc: `compiler passes  </service_container/compiler_passes >` it's recommended
390454to use the :method: `Symfony\\ Component\\ DependencyInjection\\ Compiler\\ ServiceLocatorTagPass::register `
391455method to create the service locators. This will save you some boilerplate and
0 commit comments