Make CommandBus use CommandResolverInterface

* Add CommandResolverInterface to resolve commands.
* Replace single CommandRegistry with CommandResolverInterface[]
  in CommandBus.
* Make CommandRegistry implement CommandResolverInterface.
This commit is contained in:
Chris 2024-12-15 13:24:57 +01:00
parent 585be681bd
commit 07f8ae467c
4 changed files with 95 additions and 9 deletions

View File

@ -13,30 +13,92 @@ class CommandBus implements CommandBusInterface
{
use EventEmitterTrait;
private CommandRegistry $commandRegistry;
/** @var array<CommandResolverInterface> */
private $resolvers = [];
private SplObjectStorage $connections;
private SplObjectStorage $servers;
public function __construct(CommandRegistry $commandRegistry)
public function __construct(?CommandResolverInterface $commands=null)
{
$this->commandRegistry = $commandRegistry;
if ($commands) {
$this->resolvers[] = $commands;
}
$this->connections = new SplObjectStorage();
$this->servers = new SplObjectStorage();
}
public function getRegistry(): CommandRegistry
/**
* Get the command registry
*
* @deprecated Use getCommandNames() instead
* @return null
*/
public function getRegistry(): ?CommandRegistry
{
return $this->commandRegistry;
return null; // $this->commandRegistry;
}
/**
* Add a CommandResolver
*
* @param CommandResolverInterface $resolver
* @return void
*/
public function addResolver(CommandResolverInterface $resolver): void
{
$this->resolvers[] = $resolver;
}
/**
* Get the names of defined commands
*
* @return array
*/
public function getCommandNames(): array
{
$commands = [];
foreach ($this->resolvers as $resolver) {
$commands = array_merge($commands, $resolver->getNames());
}
sort($commands);
return array_unique($commands);
}
/**
* Find a command by searching through the resolvers
*
* @param string $command
* @return Command|null
*/
public function findCommand(string $command): ?Command
{
foreach ($this->resolvers as $resolver) {
if ($found = $resolver->find($command))
return $found;
}
return null;
}
/**
* Add a server listener
*
* @param ServerInterface $server
* @return void
*/
public function addServer(ServerInterface $server): void
{
$this->servers->attach($server);
$server->on('connection', $this->onServerConnection(...));
}
/**
* Remove a server listener
*
* @param ServerInterface $server
* @return void
*/
public function removeServer(ServerInterface $server): void
{
$server->close();
@ -44,6 +106,11 @@ class CommandBus implements CommandBusInterface
$this->servers->detach($server);
}
/**
* Close and shutdown the servers
*
* @return void
*/
public function close(): void
{
foreach ($this->servers as $server) {
@ -106,7 +173,7 @@ class CommandBus implements CommandBusInterface
private function executeContext(Context $context): PromiseInterface
{
$command = $this->commandRegistry->find($context->getCommandName());
$command = $this->findCommand($context->getCommandName());
if (!$command) return new Promise(function (callable $resolve) use ($context) {
throw new \RuntimeException("Unable to resolve command: ".$context->getCommandName());
});

View File

@ -38,8 +38,8 @@ class CommandBusClient implements CommandBusInterface
{
$this->commandRegistry = $commandRegistry;
if ($commandRegistry) {
$commandRegistry->on(CommandRegistry::EVENT_REGISTERED, $this->onCommandRegistered(...));
$commandRegistry->on(CommandRegistry::EVENT_UNREGISTERED, $this->onCommandUnregistered(...));
$this->commandRegistry->on(CommandRegistry::EVENT_REGISTERED, $this->onCommandRegistered(...));
$this->commandRegistry->on(CommandRegistry::EVENT_UNREGISTERED, $this->onCommandUnregistered(...));
}
$this->connector = $connector??new TcpConnector();
}

View File

@ -8,7 +8,7 @@ use Evenement\EventEmitterTrait;
* A collection of commands that can be executed via CommandBusInterface
*
*/
class CommandRegistry implements EventEmitterInterface
class CommandRegistry implements CommandResolverInterface, EventEmitterInterface
{
use EventEmitterTrait;

View File

@ -0,0 +1,19 @@
<?php
namespace NoccyLabs\React\CommandBus;
use Evenement\EventEmitterInterface;
use Evenement\EventEmitterTrait;
/**
* A collection of commands that can be executed via CommandBusInterface
*
*/
interface CommandResolverInterface
{
public function find(string $command): ?Command;
public function getNames(): array;
}