Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up

Library to create the domain layer of your DDD application

License

NotificationsYou must be signed in to change notification settings

gpslab/domain-event-bundle

Repository files navigation

Latest Stable VersionPHP Version SupportTotal DownloadsBuild StatusCoverage StatusScrutinizer Code QualityLicense

Domain event bundle

Bundle to create the domain layer of yourDomain-driven design (DDD) application.

ThisSymfony bundle is a wrapper forgpslab/domain-event, look it for more details.

Installation

Pretty simple withComposer, run:

composer req gpslab/domain-event-bundle

Configuration

Example configuration

gpslab_domain_event:# Event bus service# Support 'listener_located', 'queue' or a custom service# As a default used 'listener_located'bus:'listener_located'# Event queue service# Support 'pull_memory', 'subscribe_executing' or a custom service# As a default used 'pull_memory'queue:'pull_memory'# Event listener locator# Support 'symfony', 'container', 'direct_binding' or custom service# As a default used 'symfony'locator:'symfony'# Publish domain events post a Doctrine flush event# As a default used 'false'publish_on_flush:true

Usage

Create a domain event

useGpsLab\Domain\Event\Eventclass PurchaseOrderCreatedEventimplements Event{    private$customer_id;private$create_at;publicfunction__construct(CustomerId$customer_id,\DateTimeImmutable$create_at)    {$this->customer_id =$customer_id;$this->create_at =$create_at;    }publicfunctioncustomerId():CustomerId    {return$this->customer_id;    }publicfunctioncreateAt():\DateTimeImmutable    {return$this->create_at;    }}

Raise your event

useGpsLab\Domain\Event\Aggregator\AbstractAggregateEvents;finalclass PurchaseOrderextends AbstractAggregateEvents{private$customer_id;private$create_at;publicfunction__construct(CustomerId$customer_id)    {$this->customer_id =$customer_id;$this->create_at =new \DateTimeImmutable();$this->raise(newPurchaseOrderCreatedEvent($customer_id,$this->create_at));    }}

Create listener

useGpsLab\Domain\Event\Event;class SendEmailOnPurchaseOrderCreated{private$mailer;publicfunction__construct(\Swift_Mailer$mailer)    {$this->mailer =$mailer;    }publicfunctiononPurchaseOrderCreated(PurchaseOrderCreatedEvent$event):void    {$message =$this->mailer            ->createMessage()            ->setTo('recipient@example.com')            ->setBody(sprintf('Purchase order created at %s for customer #%s',$event->createAt()->format('Y-m-d'),$event->customerId()            ));$this->mailer->send($message);    }}

Register event listener

services:SendEmailOnPurchaseOrderCreated:arguments:[ '@mailer' ]tags:            -{ name: domain_event.listener, event: PurchaseOrderCreatedEvent, method: onPurchaseOrderCreated }

Publish events in listener

useGpsLab\Domain\Event\Bus\EventBus;// get event bus from DI container$bus =$this->get(EventBus::class);// do what you need to do on your Domain$purchase_order =newPurchaseOrder(newCustomerId(1));// this will clear the list of event in your AggregateEvents so an Event is trigger only once$events =$purchase_order->pullEvents();// You can have more than one event at a time.foreach($eventsas$event) {$bus->publish($event);}// You can use one method//$bus->pullAndPublish($purchase_order);

Listener method name

You do not need to specify the name of the event handler method. By default, the__invoke method is used.

useGpsLab\Domain\Event\Event;class SendEmailOnPurchaseOrderCreated{private$mailer;publicfunction__construct(\Swift_Mailer$mailer)    {$this->mailer =$mailer;    }publicfunction__invoke(PurchaseOrderCreatedEvent$event):void    {$message =$this->mailer            ->createMessage()            ->setTo('recipient@example.com')            ->setBody(sprintf('Purchase order created at %s for customer #%s',$event->createAt()->format('Y-m-d'),$event->customerId()            ));$this->mailer->send($message);    }}

Register event listener

services:SendEmailOnPurchaseOrderCreated:arguments:[ '@mailer' ]tags:            -{ name: domain_event.listener, event: PurchaseOrderCreatedEvent }

Event subscribers

Create subscriber

useGpsLab\Domain\Event\Event;useGpsLab\Domain\Event\Listener\Subscriber;class SendEmailOnPurchaseOrderCreatedimplements Subscriber{private$mailer;publicfunction__construct(\Swift_Mailer$mailer)    {$this->mailer =$mailer;    }publicstaticfunctionsubscribedEvents():array    {return [            PurchaseOrderCreatedEvent::class => ['onPurchaseOrderCreated'],        ];    }publicfunctiononPurchaseOrderCreated(PurchaseOrderCreatedEvent$event):void    {$message =$this->mailer            ->createMessage()            ->setTo('recipient@example.com')            ->setBody(sprintf('Purchase order created at %s for customer #%s',$event->createAt()->format('Y-m-d'),$event->customerId()            ));$this->mailer->send($message);    }}

Register event subscriber

services:SendEmailOnPurchaseOrderCreated:arguments:[ '@mailer' ]tags:            -{ name: domain_event.subscriber }

Use pull Predis queue

InstallPredis withComposer, run:

composer require predis/predis

Register services:

services:# PredisPredis\Client:arguments:[ '127.0.0.1' ]# Events serializer for queueGpsLab\Domain\Event\Queue\Serializer\SymfonySerializer:arguments:[ '@serializer', 'json' ]# Predis event queueGpsLab\Domain\Event\Queue\Pull\PredisPullEventQueue:arguments:            -'@Predis\Client'            -'@GpsLab\Domain\Event\Queue\Serializer\SymfonySerializer'            -'@logger'            -'event_queue_name'

Change config for use custom queue:

gpslab_domain_event:queue:'GpsLab\Domain\Event\Queue\Pull\PredisPullEventQueue'

And now you can use custom queue:

useGpsLab\Domain\Event\Queue\EventQueue;$container->get(EventQueue::class)->publish($domain_event);

In latter pull events from queue:

useGpsLab\Domain\Event\Queue\EventQueue;$queue =$container->get(EventQueue::class);$bus =$container->get(EventQueue::class);while ($event =$queue->pull()) {$bus->publish($event);}

Use Predis subscribe queue

InstallPredis PubSub adapter withComposer, run:

composer require superbalist/php-pubsub-redis

Register services:

services:# PredisPredis\Client:arguments:[ '127.0.0.1' ]# Predis PubSub adapterSuperbalist\PubSub\Redis\RedisPubSubAdapter:arguments:[ '@Predis\Client' ]# Events serializer for queueGpsLab\Domain\Event\Queue\Serializer\SymfonySerializer:arguments:[ '@serializer', 'json' ]# Predis event queueGpsLab\Domain\Event\Queue\Subscribe\PredisSubscribeEventQueue:arguments:            -'@Superbalist\PubSub\Redis\RedisPubSubAdapter'            -'@GpsLab\Domain\Event\Queue\Serializer\SymfonySerializer'            -'@logger'            -'event_queue_name'

Change config for use custom queue:

gpslab_domain_event:queue:'GpsLab\Domain\Event\Queue\Subscribe\PredisSubscribeEventQueue'

And now you can use custom queue:

useGpsLab\Domain\Event\Queue\EventQueue;$container->get(EventQueue::class)->publish($domain_event);

Subscribe on the queue:

useGpsLab\Domain\Event\Queue\EventQueue;$container->get(EventQueue::class)->subscribe(function (Event$event) {// do somthing});

Note

You can use subscribe handlers as a services andtag itfor optimize register.

Many queues

You can use many queues for separation the flows. For example, you want to handle events of different Bounded Contextsseparately from each other.

services:acme.domain.purchase_order.event.queue:class:GpsLab\Domain\Event\Queue\Pull\PredisPullEventQueuearguments:            -'@Superbalist\PubSub\Redis\RedisPubSubAdapter'            -'@GpsLab\Domain\Event\Queue\Serializer\SymfonySerializer'            -'@logger'            -'purchase_order_event_queue'acme.domain.article_comment.event.queue:class:GpsLab\Domain\Event\Queue\Pull\PredisPullEventQueuearguments:            -'@Superbalist\PubSub\Redis\RedisPubSubAdapter'            -'@GpsLab\Domain\Event\Queue\Serializer\SymfonySerializer'            -'@logger'            -'article_comment_event_queue'

And now you can use a different queues.

InPurchase order Bounded Contexts.

$event =newPurchaseOrderCreatedEvent(newCustomerId(1),new \DateTimeImmutable());$container->get('acme.domain.purchase_order.event.queue')->publish($event);

InArticle comment Bounded Contexts.

$event =newArticleCommentedEvent(newArticleId(1),newAuthorId(1),$comment    new\DateTimeImmutable());$container->get('acme.domain.article_comment.event.queue')->publish($event);

Note

Similarly, you can split the subscribe queues.

License

This bundle is under theMIT license. See the complete license in the file: LICENSE


[8]ページ先頭

©2009-2025 Movatter.jp