ashleydawson / domain-event-dispatcher
从单例中分发或延迟领域事件。如果你使用领域驱动设计(DDD)并且需要一个单例领域分发器来处理模型,这将非常有用。
1.0.6
2016-12-23 12:10 UTC
Requires
- php: >=5.5
Requires (Dev)
- phpunit/phpunit: ^4.0
README
用于领域驱动设计(DDD)的单例领域事件分发器。领域事件分发器是单例的,因此可以轻松地在模型内部使用。
安装
使用以下命令通过Composer安装
$ composer require ashleydawson/domain-event-dispatcher
基本用法
定义要分发的事件。事件类可以是任何类型,并且应该易于序列化。
<?php namespace Acme\Event; class MyEvent { }
定义事件监听器
<?php namespace Acme\EventListener; use Acme\Event\MyEvent; class MyTypedEventListener { // Domain event listeners must implement the __invoke() magic method with only one argument public function __invoke(MyEvent $event) { // Do something useful here... } }
将所有内容组合在一起,添加你的监听器并分发。
<?php require __DIR__.'/vendor/autoload.php'; use AshleyDawson\DomainEventDispatcher\DomainEventDispatcher; use Acme\Event\MyEvent; use Acme\EventListener\MyTypedEventListener; // Add your listener to the dispatcher DomainEventDispatcher::getInstance()->addListener( new MyTypedEventListener() ); // Dispatch the event from within your domain, e.g. from your domain model, etc. DomainEventDispatcher::getInstance()->dispatch( new MyEvent() );
监听器类型
有两种类型的监听器
通用
- 由 任何 领域事件调用。类型化
- 由相应类型的事件调用。
通用监听器
在之前的示例中,我们看到事件分发器被用于类型化事件,其中事件参数在事件监听器的 __invoke()
方法中被类型提示。通用监听器由所有事件调用,并且没有类型提示。例如
<?php namespace Acme\EventListener; class MyEventGeneralListener { // Event is not type hinted as this is a general event listener - it will be invoked by all events public function __invoke($event) { // Do something useful here... } }
类型化监听器
类型化监听器仅响应特定类型的领域事件
<?php namespace Acme\EventListener; use Acme\Event\MyEvent; class MyEventGeneralListener { // This listener will only respond to MyEvent events public function __invoke(MyEvent $event) { // Do something useful here... } }
延迟事件
有时在应用程序流程的稍后阶段分发事件可能很有用。为此,事件可以延迟并稍后分发。
<?php require __DIR__.'/vendor/autoload.php'; use AshleyDawson\DomainEventDispatcher\DomainEventDispatcher; use Acme\Event\MyEvent; use Acme\EventListener\MyTypedEventListener; // Add your listener to the dispatcher DomainEventDispatcher::getInstance()->addListener( new MyTypedEventListener() ); // Dispatch the event from within your domain, e.g. from your domain model, etc. DomainEventDispatcher::getInstance()->defer( new MyEvent() ); // From a different level of the application, dispatch the deferred events DomainEventDispatcher::getInstance()->dispatchDeferred();
领域事件存储
为了事件发布、通知或审计目的,您可能需要将事件存储在事件存储中。为此,只需实现 EventStoreInterface
<?php namespace Acme\DomainEventStorage; use AshleyDawson\DomainEventDispatcher\EventStorage\EventStoreInterface; class InMemoryEventStore implements EventStoreInterface { private $events = []; public function append($event) { $this->events[] = $event; } }
然后配置事件分发器以使用事件存储
<?php use AshleyDawson\DomainEventDispatcher\DomainEventDispatcher; use Acme\DomainEventStorage\InMemoryEventStore; DomainEventDispatcher::getInstance()->setEventStore( new InMemoryEventStore() );
重要:如果配置了事件存储,事件分发器将尝试存储 所有事件。如果您不希望事件分发器存储特定事件,请在事件上实现 DisposableEventInterface
<?php namespace Acme\Event; use AshleyDawson\DomainEventDispatcher\EventStorage\DisposableEventInterface; class MyDisposableEvent implements DisposableEventInterface { }
测试
要运行测试套件,请执行以下操作
$ php bin/phpunit