Skip to content

Event Bus

Optionally you can use an event bus to dispatch events to listeners.

For all events that are persisted (when the save method has been executed on the repository), the event wrapped in a message will be dispatched to the event bus. All listeners are then called for each message.

Tip

It is recommended to use the subscription engine to process the messages. It is more powerful and flexible than the event bus.

Event Bus

The library delivers a light-weight event bus for which you can register listeners and dispatch events.

use Patchlevel\EventSourcing\EventBus\DefaultEventBus;

$eventBus = DefaultEventBus::create([$mailListener]);

Note

The order in which the listeners are executed is determined by the order in which they are passed to the factory.

Internally, the event bus uses the Consumer to consume the messages and call the listeners.

Consumer

The consumer is responsible for consuming the messages and calling the listeners.

use Patchlevel\EventSourcing\EventBus\DefaultConsumer;

$consumer = DefaultConsumer::create([$mailListener]);

$consumer->consume($message);
Internally, the consumer uses the ListenerProvider to find the listeners for the message.

Listener provider

The listener provider is responsible for finding all listeners for a specific event. The default listener provider uses attributes to find the listeners.

use Patchlevel\EventSourcing\EventBus\AttributeListenerProvider;
use Patchlevel\EventSourcing\EventBus\DefaultConsumer;
use Patchlevel\EventSourcing\EventBus\DefaultEventBus;

$listenerProvider = new AttributeListenerProvider([$mailListener]);

$eventBus = new DefaultEventBus(
    new DefaultConsumer($listenerProvider),
);

Tip

The DefaultEventBus::create method uses the DefaultConsumer and AttributeListenerProvider by default.

Custom listener provider

You can also use your own listener provider.

use Patchlevel\EventSourcing\EventBus\ListenerDescriptor;
use Patchlevel\EventSourcing\EventBus\ListenerProvider;

$listenerProvider = new class implements ListenerProvider {
    public function listenersForEvent(string $eventClass): iterable
    {
        return [
            new ListenerDescriptor(
                (new WelcomeSubscriber())->onProfileCreated(...),
            ),
        ];
    }
};

Tip

You can use $listenerDiscriptor->name() to get the name of the listener.

Listener

You can listen for specific events with the attribute Subscribe. This listener is then called for all saved events / messages.

use Patchlevel\EventSourcing\Attribute\Subscribe;
use Patchlevel\EventSourcing\Message\Message;

final class WelcomeSubscriber
{
    #[Subscribe(ProfileCreated::class)]
    public function onProfileCreated(Message $message): void
    {
        echo 'Welcome!';
    }
}

Tip

If you use psalm, you can use the event sourcing plugin for better type support.

Listen on all events

If you want to listen on all events, you can pass * or Subscribe::ALL instead of the event class.

use Patchlevel\EventSourcing\Attribute\Subscribe;
use Patchlevel\EventSourcing\Message\Message;

final class WelcomeSubscriber
{
    #[Subscribe('*')]
    public function onProfileCreated(Message $message): void
    {
        echo 'Welcome!';
    }
}

Psr-14 Event Bus

You can also use a psr-14 compatible event bus. In this case, you can't use the Subscribe attribute. You need to use the system of the psr-14 event bus.

use Patchlevel\EventSourcing\EventBus\Psr14EventBus;

$eventBus = new Psr14EventBus($psr14EventDispatcher);

Warning

You can't use the Subscribe attribute with the psr-14 event bus.

Learn more