Skip to content

some tweaks for the service locator chapter #8398

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Oct 13, 2017
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
some tweaks for the service locator chapter
  • Loading branch information
xabbuh committed Sep 15, 2017
commit 47e28dd5d6aa8ffd998a8f981db5c486bf24f92b
48 changes: 27 additions & 21 deletions service_container/service_locators.rst
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,9 @@ A real-world example are applications that implement the `Command pattern`_
using a CommandBus to map command handlers by Command class names and use them
to handle their respective command when it is asked for::

// src/AppBundle/CommandBus.php
namespace AppBundle;

// ...
class CommandBus
{
Expand Down Expand Up @@ -46,28 +49,29 @@ Considering that only one command is handled at a time, instantiating all the
other command handlers is unnecessary. A possible solution to lazy-load the
handlers could be to inject the whole dependency injection container::

use Symfony\Component\DependencyInjection\ContainerInterface;
// ...
use Symfony\Component\DependencyInjection\ContainerInterface;

class CommandBus
{
private $container;
class CommandBus
{
private $container;

public function __construct(ContainerInterface $container)
{
$this->container = $container;
}
public function __construct(ContainerInterface $container)
{
$this->container = $container;
}

public function handle(Command $command)
{
$commandClass = get_class($command);
public function handle(Command $command)
{
$commandClass = get_class($command);

if ($this->container->has($commandClass)) {
$handler = $this->container->get($commandClass);
if ($this->container->has($commandClass)) {
$handler = $this->container->get($commandClass);

return $handler->handle($command);
}
return $handler->handle($command);
}
}
}

However, injecting the entire container is discouraged because it gives too
broad access to existing services and it hides the actual dependencies of the
Expand All @@ -87,8 +91,8 @@ option to include as many services as needed to it and add the

.. code-block:: yaml

// app/config/services.yml
services:

app.command_handler_locator:
class: Symfony\Component\DependencyInjection\ServiceLocator
tags: ['container.service_locator']
Expand All @@ -99,6 +103,7 @@ option to include as many services as needed to it and add the

.. code-block:: xml

<!-- app/config/services.xml -->
<?xml version="1.0" encoding="UTF-8" ?>
<container xmlns="http://symfony.com/schema/dic/services"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
Expand All @@ -119,6 +124,7 @@ option to include as many services as needed to it and add the

.. code-block:: php

// app/config/services.php
use Symfony\Component\DependencyInjection\ServiceLocator;
use Symfony\Component\DependencyInjection\Reference;

Expand All @@ -144,13 +150,14 @@ Now you can use the service locator injecting it in any other service:

.. code-block:: yaml

// app/config/services.yml
services:

AppBundle\CommandBus:
arguments: ['@app.command_handler_locator']

.. code-block:: xml

<!-- app/config/services.xml -->
<?xml version="1.0" encoding="UTF-8" ?>
<container xmlns="http://symfony.com/schema/dic/services"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
Expand All @@ -159,19 +166,18 @@ Now you can use the service locator injecting it in any other service:
<services>

<service id="AppBundle\CommandBus">
<argument type="service" id="app.command_handler.locator" />
<argument type="service" id="app.command_handler_locator" />
</service>

</services>
</container>

.. code-block:: php

// app/config/services.php
use AppBundle\CommandBus;
use Symfony\Component\DependencyInjection\Reference;

//...

$container
->register(CommandBus::class)
->setArguments(array(new Reference('app.command_handler_locator')))
Expand All @@ -185,7 +191,7 @@ Now you can use the service locator injecting it in any other service:
Usage
-----

Back to the previous CommandBus example, it looks like this when using the
Back to the previous ``CommandBus`` example, it looks like this when using the
service locator::

// ...
Expand Down