In order to improve my skills, I'm doing my own implementation of a CommandBus.
composer require blacksmith-project/command-bus
- Your handlers need to
- be callable (implements an
__invoke()
method). - be named after the command they handle:
$command = new AddSugarToCoffee(); $handler = new AddSugarToCoffeeHandler();
- be callable (implements an
- Handlers must be added to a
CommandHandlerMap
:$map = new SimpleCommandHandlerMap([$handler, $anotherHandler]); $map->add($yetAnotherHandler);
- Your
CommandBus
takes as parameter aCommandHandlerMap
.
- Declare your Handlers as a Service.
- Tag them with a specific tag such as
my_app.command_handler
. - Declare your
CommandHandlerMap
as a Service. - Make it use the tagged
my_app.command_handler
services as arguments. - Declare your
CommandBus
as a Service. - Make it use the
CommandHandlerMap
as argument.
# config/services.yaml
############
# Commands #
############
MyApp\Domain\ACommandHandler:
tags:
- 'my_app.command_handler'
MyApp\Domain\AnothenCommandHandler:
tags:
- 'my_app.command_handler'
########################
# CommandHandlerMapper #
########################
BSP\CommandBus\SimpleCommandHandlerMap:
arguments: [!tagged my_app.command_handler]
##############
# CommandBus #
##############
BSP\CommandBus\SimpleCommandBus:
arguments:
- BSP\CommandBus\SimpleCommandHandlerMap
Now, you only need to inject your CommandBus
and execute commands.
public function __construct(CommandBus $commandBus)
{
$this->commandBus = $commandBus;
}
public function doSomethingFromCLI(): void
{
$command = new DoSomething('please');
$this->commandBus->execute($command);
$output->writeln('command has been executed.');
}