Install the Package
composer require dlakomski/symfony-bridge
(Note: The package is a fork of simplebus/symfony-bridge; verify compatibility with your Symfony version.)
Enable Bundles
Add to config/bundles.php:
return [
// ...
SimpleBus\SymfonyBridge\CommandBusBundle\CommandBusBundle::class => ['all' => true],
SimpleBus\SymfonyBridge\EventBusBundle\EventBusBundle::class => ['all' => true],
// Optional: Doctrine integration
SimpleBus\SymfonyBridge\DoctrineORMBridgeBundle\DoctrineORMBridgeBundle::class => ['all' => true],
];
Configure the Bus
Define a command/event bus in config/packages/simple_bus.yaml:
simple_bus:
command_bus:
middleware: ['@simple_bus.middleware.doctrine_transaction', '@simple_bus.middleware.logger']
event_bus:
middleware: ['@simple_bus.middleware.doctrine_transaction']
First Use Case: Dispatch a Command
use SimpleBus\MessageBus\MessageBus;
use App\Command\CreateUserCommand;
class UserService {
public function __construct(private MessageBus $commandBus) {}
public function createUser(string $name) {
$this->commandBus->dispatch(new CreateUserCommand($name));
}
}
Command Bus
MessageBus interface to send commands (e.g., CreateUserCommand).SimpleBus\MessageBus\Message\MessageHandlerInterface for commands.
class CreateUserHandler implements MessageHandlerInterface {
public function handle(CreateUserCommand $command) {
// Business logic
}
}
config/packages/simple_bus.yaml.Event Bus
EventBus (e.g., UserCreatedEvent).EventSubscriberInterface or annotations.
#[AsEventListener]
class UserCreatedListener {
public function __invoke(UserCreatedEvent $event) {
// React to event
}
}
Doctrine Integration
DoctrineTransactionMiddleware.simple_bus.yaml:
simple_bus:
command_bus:
middleware: ['@simple_bus.middleware.doctrine_transaction']
MessageBus (for commands) or EventBus (for events) into services.SimpleBus\MessageBus\Test\MessageBusTestCase for isolated command/event tests.AsyncCommandBus).Middleware Order Matters
simple_bus.yaml. Place DoctrineTransactionMiddleware last to ensure transactions wrap the entire handler chain.Circular Dependencies
MessageBus into event handlers or command handlers (risk of infinite loops). Use services instead.Doctrine Entity Lifecycle
DoctrineTransactionMiddleware, ensure entities are managed before dispatching commands (e.g., entityManager->persist()).Symfony 6+ Compatibility
composer.json for supported versions.@simple_bus.middleware.logger to debug message flow:
simple_bus:
command_bus:
middleware: ['@simple_bus.middleware.logger']
autoconfigure: true helps).Custom Middleware
Create middleware classes implementing SimpleBus\MessageBus\Middleware\Middleware:
class ValidateCommandMiddleware implements Middleware {
public function handle($message, callable $next) {
if (!$this->isValid($message)) {
throw new \RuntimeException("Invalid command");
}
return $next($message);
}
}
Register in simple_bus.yaml:
simple_bus:
command_bus:
middleware: ['@validate_command']
Event Listener Priorities
Use Symfony’s priority option in annotations or YAML to control listener order:
#[AsEventListener(priority: 10)]
Async Command Bus
Extend SimpleBus\SymfonyBridge\CommandBusBundle\CommandBus to delegate to Symfony Messenger:
class AsyncCommandBus extends CommandBus {
public function dispatch($command) {
$this->messenger->dispatch($command);
}
}
How can I help you explore Laravel packages today?