Skip to content

Commit be11a7e

Browse files
author
Jeroen de Graaf
committed
Showcase new feature domain command handlers
Converting all use cases to use the new attribute `#[DomainCommandHandler]`, except the classic aggregate root 'use cases' (to show both are possible).
1 parent 7356390 commit be11a7e

25 files changed

+123
-207
lines changed

README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ Instead, a hybrid solution with aggregates and use cases is probably more likely
1010
This example project is using a fictive domain (taken from Sara Pellegrini's blog) where students can subscribe to courses (of any kind).
1111
Deliberately this is all what is defined for this domain, to focus on how this could be implemented when using Event Sourcing with the DCB pattern in mind.
1212

13-
It contains both classic aggregates (e.g. [Course](src/Domain/Course/Course.php), [Student](src/Domain/Student/Student.php)) as well as use cases (e.g. [ChangeCourseCapacity](src/Domain/Course/ChangeCourseCapacity.php), [SubscribeStudentToCourse](src/Domain/StudentToCourseSubscription/SubscribeStudentToCourse.php), [UnsubscribeStudentFromCourse](src/Domain/StudentToCourseSubscription/UnsubscribeStudentFromCourse.php)).
13+
It contains both classic aggregates (e.g. [Course](src/Domain/Course/Course.php), [Student](src/Domain/Student/Student.php)) as well as use cases (e.g. [ChangeCourseCapacity](src/Domain/ChangeCourseCapacity/ChangeCourseCapacity.php), [SubscribeStudentToCourse](src/Domain/SubscribeStudentToCourse/SubscribeStudentToCourse.php), [UnsubscribeStudentFromCourse](src/Domain/UnsubscribeStudentFromCourse/UnsubscribeStudentFromCourse.php)).
1414

1515
Inspired by other PHP libraries such as [Broadway](https://github.com/broadway), [EventSauce](https://github.com/EventSaucePHP), [Prooph](https://github.com/prooph) and [Ecotone](https://github.com/ecotoneframework) as well as [Axon Framework](https://github.com/AxonFramework) for Java.
1616

config/packages/gember_event_sourcing.yaml

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3,12 +3,17 @@ gember_event_sourcing:
33
enabled: true
44
psr6:
55
service: '@cache.app'
6-
event_registry:
7-
reflector:
8-
path: '%kernel.project_dir%/src/Domain'
6+
registry:
7+
event:
8+
reflector:
9+
path: '%kernel.project_dir%/src/Domain'
10+
command_handler:
11+
reflector:
12+
path: '%kernel.project_dir%/src/Domain'
913
message_bus:
1014
symfony:
1115
event_bus: '@event.bus'
16+
command_bus: '@command.bus'
1217
event_store:
1318
rdbms:
1419
doctrine_dbal:

src/Application/Command/Course/ChangeCourseCapacityCommand.php

Lines changed: 0 additions & 16 deletions
This file was deleted.

src/Application/Command/Course/ChangeCourseCapacityHandler.php

Lines changed: 0 additions & 35 deletions
This file was deleted.

src/Application/Command/StudentToCourseSubscription/SubscribeStudentToCourseCommand.php

Lines changed: 0 additions & 16 deletions
This file was deleted.

src/Application/Command/StudentToCourseSubscription/SubscribeStudentToCourseHandler.php

Lines changed: 0 additions & 46 deletions
This file was deleted.

src/Application/Command/StudentToCourseSubscription/UnsubscribeStudentFromCourseCommand.php

Lines changed: 0 additions & 16 deletions
This file was deleted.

src/Application/Command/StudentToCourseSubscription/UnsubscribeStudentFromCourseHandler.php

Lines changed: 0 additions & 42 deletions
This file was deleted.

src/Domain/Course/ChangeCourseCapacity.php renamed to src/Domain/ChangeCourseCapacity/ChangeCourseCapacity.php

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2,12 +2,16 @@
22

33
declare(strict_types=1);
44

5-
namespace Gember\ExampleEventSourcingDcb\Domain\Course;
5+
namespace Gember\ExampleEventSourcingDcb\Domain\ChangeCourseCapacity;
66

7+
use Gember\EventSourcing\UseCase\Attribute\DomainCommandHandler;
78
use Gember\EventSourcing\UseCase\Attribute\DomainEventSubscriber;
89
use Gember\EventSourcing\UseCase\Attribute\DomainTag;
910
use Gember\EventSourcing\UseCase\EventSourcedUseCase;
1011
use Gember\EventSourcing\UseCase\EventSourcedUseCaseBehaviorTrait;
12+
use Gember\ExampleEventSourcingDcb\Domain\Course\CourseCreatedEvent;
13+
use Gember\ExampleEventSourcingDcb\Domain\Course\CourseId;
14+
use Gember\ExampleEventSourcingDcb\Domain\Course\CourseNotFoundException;
1115

1216
/**
1317
* Use case based one domain tag.
@@ -30,12 +34,13 @@ final class ChangeCourseCapacity implements EventSourcedUseCase
3034
/**
3135
* @throws CourseNotFoundException
3236
*/
33-
public function changeCapacity(int $capacity): void
37+
#[DomainCommandHandler]
38+
public function __invoke(ChangeCourseCapacityCommand $command): void
3439
{
3540
/*
3641
* Guard for idempotency.
3742
*/
38-
if ($this->capacity === $capacity) {
43+
if ($this->capacity === $command->capacity) {
3944
return;
4045
}
4146

@@ -47,7 +52,7 @@ public function changeCapacity(int $capacity): void
4752
/*
4853
* Apply events when all business rules are met.
4954
*/
50-
$this->apply(new CourseCapacityChangedEvent((string) $this->courseId, $capacity));
55+
$this->apply(new CourseCapacityChangedEvent((string) $this->courseId, $command->capacity));
5156
}
5257

5358
/**
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 Gember\ExampleEventSourcingDcb\Domain\ChangeCourseCapacity;
6+
7+
use Gember\EventSourcing\UseCase\Attribute\DomainTag;
8+
use Gember\ExampleEventSourcingDcb\Domain\Course\CourseId;
9+
10+
/**
11+
* @see ChangeCourseCapacity
12+
*/
13+
final readonly class ChangeCourseCapacityCommand
14+
{
15+
public function __construct(
16+
#[DomainTag]
17+
public CourseId $courseId,
18+
public int $capacity,
19+
) {}
20+
}

0 commit comments

Comments
 (0)