Skip to content

Bus restricting with Interfaces #13239

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
Nov 22, 2020
Merged
Show file tree
Hide file tree
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
79 changes: 46 additions & 33 deletions messenger/multiple_buses.rst
Original file line number Diff line number Diff line change
Expand Up @@ -150,30 +150,30 @@ you can restrict each handler to a specific bus using the ``messenger.message_ha
This way, the ``App\MessageHandler\SomeCommandHandler`` handler will only be
known by the ``command.bus`` bus.

You can also automatically add this tag to a number of classes by following
a naming convention and registering all of the handler services by name with
the correct tag:
You can also automatically add this tag to a number of classes by using
the :ref:`_instanceof service configuration <di-instanceof>`. Using this,
you can determine the message bus based on an implemented interface:

.. configuration-block::

.. code-block:: yaml

# config/services.yaml
services:
# ...

_instanceof:
# all services implementing the CommandHandlerInterface
# will be registered on the command.bus bus
App\MessageHandler\CommandHandlerInterface:
tags:
- { name: messenger.message_handler, bus: command.bus }

# put this after the "App\" line that registers all your services
command_handlers:
namespace: App\MessageHandler\
resource: '%kernel.project_dir%/src/MessageHandler/*CommandHandler.php'
autoconfigure: false
tags:
- { name: messenger.message_handler, bus: command.bus }

query_handlers:
namespace: App\MessageHandler\
resource: '%kernel.project_dir%/src/MessageHandler/*QueryHandler.php'
autoconfigure: false
tags:
- { name: messenger.message_handler, bus: query.bus }
# while those implementing QueryHandlerInterface will be
# registered on the query.bus bus
App\MessageHandler\QueryHandlerInterface:
tags:
- { name: messenger.message_handler, bus: query.bus }

.. code-block:: xml

Expand All @@ -185,32 +185,45 @@ the correct tag:
https://symfony.com/schema/dic/services/services-1.0.xsd">

<services>
<!-- command handlers -->
<prototype namespace="App\MessageHandler\" resource="%kernel.project_dir%/src/MessageHandler/*CommandHandler.php" autoconfigure="false">
<!-- ... -->

<!-- all services implementing the CommandHandlerInterface
will be registered on the command.bus bus -->
<instanceof id="App\MessageHandler\CommandHandlerInterface">
<tag name="messenger.message_handler" bus="command.bus"/>
</prototype>
<!-- query handlers -->
<prototype namespace="App\MessageHandler\" resource="%kernel.project_dir%/src/MessageHandler/*QueryHandler.php" autoconfigure="false">
</instanceof>

<!-- while those implementing QueryHandlerInterface will be
registered on the query.bus bus -->
<instanceof id="App\MessageHandler\QueryHandlerInterface">
<tag name="messenger.message_handler" bus="query.bus"/>
</prototype>
</instanceof>
</services>
</container>

.. code-block:: php

// config/services.php
namespace Symfony\Component\DependencyInjection\Loader\Configurator;

// Command handlers
$container->services()
->load('App\MessageHandler\\', '%kernel.project_dir%/src/MessageHandler/*CommandHandler.php')
->autoconfigure(false)
->tag('messenger.message_handler', ['bus' => 'command.bus']);
use App\MessageHandler\CommandHandlerInterface;
use App\MessageHandler\QueryHandlerInterface;

// Query handlers
$container->services()
->load('App\MessageHandler\\', '%kernel.project_dir%/src/MessageHandler/*QueryHandler.php')
->autoconfigure(false)
->tag('messenger.message_handler', ['bus' => 'query.bus']);
return function(ContainerConfigurator $configurator) {
$services = $configurator->services();

// ...

// all services implementing the CommandHandlerInterface
// will be registered on the command.bus bus
$services->instanceof(CommandHandlerInterface::class)
->tag('messenger.message_handler', ['bus' => 'command.bus']);

// while those implementing QueryHandlerInterface will be
// registered on the query.bus bus
$services->instanceof(QueryHandlerInterface::class)
->tag('messenger.message_handler', ['bus' => 'query.bus']);
};

Debugging the Buses
-------------------
Expand Down
2 changes: 2 additions & 0 deletions service_container/tags.rst
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,8 @@ and many tags require additional arguments (beyond the ``name`` parameter).
**For most users, this is all you need to know**. If you want to go further and
learn how to create your own custom tags, keep reading.

.. _di-instanceof:

Autoconfiguring Tags
--------------------

Expand Down