Skip to content

Commit 15db081

Browse files
author
Antoine Lelaisant
committed
step 10: introduce domain events
1 parent 95ccd9c commit 15db081

File tree

19 files changed

+354
-11
lines changed

19 files changed

+354
-11
lines changed

config/packages/messenger.yaml

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,16 @@ framework:
66

77
buses:
88
command.bus:
9+
default_middleware: true
910
middleware:
11+
- Infrastructure\Symfony\Messenger\Middleware\DomainEventDispatcher
12+
- dispatch_after_current_bus
1013
- doctrine_transaction
1114

1215
query.bus: ~
16+
17+
event.bus:
18+
default_middleware: allow_no_handlers
19+
middleware:
20+
- dispatch_after_current_bus
21+
- doctrine_transaction

config/services.yaml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,3 +12,5 @@ services:
1212

1313
Application\:
1414
resource: '../src/Application/'
15+
exclude:
16+
- '../src/Application/DomainEventsHandler/'

config/services/domain_events.yaml

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
---
2+
services:
3+
_defaults:
4+
autowire: true
5+
public: false
6+
7+
Domain\EventsRegisterer: ~
8+
9+
Application\DomainEventsHandler\:
10+
resource: '%kernel.project_dir%/src/Application/DomainEventsHandler/**.php'
11+
tags:
12+
- { name: messenger.message_handler, bus: event.bus }

config/services/messenger.yaml

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,9 @@ services:
55
autoconfigure: true
66
public: false
77

8+
Infrastructure\Symfony\Messenger\Middleware\:
9+
resource: '%kernel.project_dir%/src/Infrastructure/Symfony/Messenger/Middleware/**.php'
10+
811
Infrastructure\Symfony\Messenger\CommandBus:
912
$messageBus: '@command.bus'
1013

@@ -16,3 +19,9 @@ services:
1619

1720
Application\MessageBus\QueryBus:
1821
alias: Infrastructure\Symfony\Messenger\QueryBus
22+
23+
Infrastructure\Symfony\Messenger\EventBus:
24+
$messageBus: '@event.bus'
25+
26+
Application\MessageBus\EventBus:
27+
alias: Infrastructure\Symfony\Messenger\EventBus

src/Application/Controller/DinosaursController.php

Lines changed: 8 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,9 @@
55
use Application\Form\Type\DinosaurType;
66
use Application\Form\Type\SearchType;
77
use Application\MessageBus\CommandBus;
8+
use Application\MessageBus\EventBus;
89
use Application\MessageBus\QueryBus;
10+
use Domain\Event\DinosaurIsBorn;
911
use Domain\Exception\DinosaurNotFoundException;
1012
use Domain\Query\GetSingleDinosaur;
1113
use Domain\Query\GetAllDinosaurs;
@@ -22,7 +24,8 @@ class DinosaursController extends AbstractController
2224
{
2325
public function __construct(
2426
private CommandBus $commandBus,
25-
private QueryBus $queryBus
27+
private QueryBus $queryBus,
28+
private EventBus $eventBus
2629
) {}
2730

2831
#[Route('/dinosaurs', name: 'app_list_dinosaurs')]
@@ -54,15 +57,10 @@ public function list(Request $request): Response
5457
)]
5558
public function single(string $id): Response
5659
{
57-
$dinosaur = $this
58-
->dinosaursCollection
59-
->find($id)
60-
;
61-
62-
if ($dinosaur === false) {
63-
throw $this->createNotFoundException(
64-
'The dinosaur you are looking for does not exists.'
65-
);
60+
try {
61+
$dinosaur = $this->queryBus->dispatch(new GetSingleDinosaur\Query($id));
62+
} catch (DinosaurNotFoundException $e) {
63+
throw $this->createNotFoundException();
6664
}
6765

6866
return $this->render('dinosaur.html.twig', [
Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace Application\DomainEventsHandler;
6+
7+
use Domain\Event\DinosaurDied;
8+
use Domain\Event\EventInterface;
9+
use Psr\Log\LoggerInterface;
10+
use Symfony\Component\Messenger\Handler\MessageSubscriberInterface;
11+
12+
class LogWhenDinosaurDied implements MessageSubscriberInterface
13+
{
14+
public function __construct(
15+
private LoggerInterface $logger
16+
) {
17+
}
18+
19+
public function __invoke(EventInterface $event): void
20+
{
21+
if (!$event instanceof DinosaurDied) {
22+
return;
23+
}
24+
25+
$this->logger->info(sprintf(
26+
'Dinosaur %s died',
27+
$event->getDinosaurName()
28+
));
29+
}
30+
31+
public static function getHandledMessages(): iterable
32+
{
33+
yield DinosaurDied::class;
34+
}
35+
}
Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace Application\DomainEventsHandler;
6+
7+
use Domain\Collection\DinosaursCollection;
8+
use Domain\Event\DinosaurIsBorn;
9+
use Domain\Event\EventInterface;
10+
use Domain\Exception\DinosaurNotFoundException;
11+
use Domain\Model\Dinosaur;
12+
use Psr\Log\LoggerInterface;
13+
use Symfony\Component\Messenger\Handler\MessageSubscriberInterface;
14+
15+
class LogWhenDinosaurIsBorn implements MessageSubscriberInterface
16+
{
17+
public function __construct(
18+
private DinosaursCollection $dinosaursCollection,
19+
private LoggerInterface $logger
20+
) {
21+
}
22+
23+
public function __invoke(EventInterface $event): void
24+
{
25+
$dinosaurId = $event->getAggregateRootId();
26+
27+
$dinosaur = $this->dinosaursCollection->find($dinosaurId);
28+
29+
if (!$dinosaur instanceof Dinosaur) {
30+
throw new DinosaurNotFoundException($dinosaurId);
31+
}
32+
33+
$this->logger->info(sprintf(
34+
'Dinosaur %s was born',
35+
$dinosaur->getName()
36+
));
37+
}
38+
39+
public static function getHandledMessages(): iterable
40+
{
41+
yield DinosaurIsBorn::class;
42+
}
43+
}
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace Application\MessageBus;
6+
7+
interface EventBus
8+
{
9+
public function dispatch(object $event): void;
10+
}

src/Domain/Event/DinosaurDied.php

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace Domain\Event;
6+
7+
use Domain\Model\Dinosaur;
8+
9+
final class DinosaurDied implements EventInterface
10+
{
11+
private string $dinosaurName;
12+
13+
public function __construct(private Dinosaur $dinosaur)
14+
{
15+
$this->dinosaurName = $dinosaur->getName();
16+
}
17+
18+
public function getAggregateRootId(): string
19+
{
20+
return (string) $this->dinosaur->getId();
21+
}
22+
23+
public function getDinosaurName(): string
24+
{
25+
return $this->dinosaurName;
26+
}
27+
}
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace Domain\Event;
6+
7+
use Domain\Model\Dinosaur;
8+
9+
class DinosaurIsBorn implements EventInterface
10+
{
11+
public function __construct(
12+
private Dinosaur $dinosaur
13+
) {
14+
}
15+
16+
public function getAggregateRootId(): string
17+
{
18+
return (string) $this->dinosaur->getId();
19+
}
20+
}

0 commit comments

Comments
 (0)