CommandBus Builder
Closed this issue · 5 comments
What do you think about adding a simple builder?
For example:
<?php
use League\Tactician\CommandBus;
use League\Tactician\Handler\CommandHandlerMiddleware;
use League\Tactician\Handler\CommandNameExtractor\ClassNameExtractor;
use League\Tactician\Handler\CommandNameExtractor\CommandNameExtractor;
use League\Tactician\Handler\Locator\HandlerLocator;
use League\Tactician\Handler\MethodNameInflector\HandleInflector;
use League\Tactician\Handler\MethodNameInflector\MethodNameInflector;
use League\Tactician\Middleware;
class Builder
{
private $middlewares = [];
private $handlerLocator;
private $commandNameExtractor;
private $inflector;
public function __construct(
HandlerLocator $handlerLocator,
CommandNameExtractor $commandNameExtractor = null,
MethodNameInflector $inflector = null
) {
$this->handlerLocator = $handlerLocator;
$this->commandNameExtractor = $commandNameExtractor ?: new ClassNameExtractor();
$this->inflector = $inflector ?: new HandleInflector();
}
public function attachMiddleware(Middleware $middleware, $priority = null)
{
if ($priority !== null) {
$this->middlewares[$priority] = $middleware;
} else {
$this->middlewares[] = $middleware;
}
}
public function build()
{
ksort($this->middlewares);
$this->middlewares[] = new CommandHandlerMiddleware(
$this->commandNameExtractor,
$this->handlerLocator,
$this->inflector
);
return new CommandBus($this->middlewares);
}
}
And then, we can configure CommandBus using a configuration file, for example:
<?php
$builder = new Builder(new ContainerBasedLocator($container));
$middlewares = require './middlewares.php';
foreach ($middlewares as $middleware) {
if (is_array($middleware)) {
if (sizeof($middleware) != 2) {
throw new \LogicException('Invalid middleware definition.');
}
list($middleware, $priority) = $middleware;
} else {
$priority = null;
}
$builder->attachMiddleware($container->get($middleware), $priority);
}
$bus = $builder->build();
<?php
// middlewares.php
return [
[LockingMiddleware::class, -255],
[LoggingMiddleware::class, 255],
[TransactionMiddleware::class, 0],
];
Hi @kilte,
First off, sorry for the delay answering you, I was busy most of the weekend. My apologies! 😓
I like the general idea though I'm not sure how common the usecase is for it. If we were to include something similar in core, perhaps it could be a refactored version of the Quickstart setup object? Would that be interesting to you?
I would probably want to remove the priority numbers though, since I've tried to avoid these and discourage them whenever I can. The order of middleware is very important to how the app runs so I want folks to make explicit decisions on that whenever possible.
Hi @rosstuck.
Yes, QuickStart is similar and can be replaced by Builder.
About priorities, maybe you're right. In my case they are necessary, since the bus is configured from multiple places. I can implement priorities manually, it does not matter.
Finally, we can replace QuickStart by simple builder (without middleware priorities). In my opinion this will be more useful.
If you two are both on board for this, perhaps it'd be good to layout some rough API notes and square this off, then we can merge it to core. :)
@rosstuck, @sagikazarmark, I've created a pull request. Waiting for suggestions =).