Event Service Provider
Synchronous event dispatcher and listener registration infrastructure.
Responsibility
Registers EventDispatcherInterface and alias events for decoupled domain/application event handling. EventServiceProvider also reads listener definitions from events.listeners config and registers them on the dispatcher.
Listener config
Application listeners are configured in app/Config/Events.php. Keys are event class names, values are listener class lists or callables.
<?php
declare(strict_types=1);
use App\Events\UserRegisteredEvent;
use App\Listeners\SendWelcomeEmailListener;
return [
'listeners' => [
UserRegisteredEvent::class => [
SendWelcomeEmailListener::class,
],
],
];
Event DTO
Events are plain objects. Keep them small and explicit; they should carry data, not framework dependencies.
namespace App\Events;
final class UserRegisteredEvent
{
public function __construct(
private readonly string $email,
) {}
public function email(): string
{
return $this->email;
}
}
Listener
A listener can be any callable. Class-string listeners are resolved through the container, so listener classes can use constructor injection when registered as services or autowired by the container.
namespace App\Listeners;
use App\Events\UserRegisteredEvent;
final class SendWelcomeEmailListener
{
public function __invoke(UserRegisteredEvent $event): void
{
// Handle event here.
}
}
Dispatching
Prefer constructor injection in services/controllers. Direct container access is useful in factories or examples where the container is already available.
use App\Events\UserRegisteredEvent;
use Lemonade\Framework\Event\EventDispatcherInterface;
final class ExampleService
{
public function __construct(
private readonly EventDispatcherInterface $events,
) {}
public function run(): void
{
$this->events->dispatch(new UserRegisteredEvent('user@example.test'));
}
}
Runtime behavior
Events are synchronous: dispatch() invokes matching listeners before returning the event object. The dispatcher matches listeners registered for the exact event class, parent classes and implemented interfaces. Listener priority is available programmatically through addListener($eventClass, $listener, priority: 10); Events.php config registers listeners with default priority.
Events are not queue
EventServiceProvider does not make work asynchronous. Use events for in-process decoupling. For background jobs, retries or workers, use QueueBusInterface and QueueServiceProvider instead.