DDD, CQRS & ES: Lessons Learned (and walls bumped into) @GitteTitter proq.blogspot.com
Jun 26, 2015
DDD, CQRS & ES: Lessons Learned
(and walls bumped into)
@GitteTitterproq.blogspot.com
One does not simply
Use DDD, CQRS & ES
UI
Commands
Command Bus
Command
Command Handler
Domain Model
Domain Model
Domain Model
Repository
Event Store
Aggregates
Events
Event Bus Event Handler
Data
Thin Data Layer
Query DTO
Events
https://github.com/MarkNijhof/Fohjin
Problem 1
“Every ‘dossier’, ‘scan’, ‘decision’, ... Should have a unique incremental number”
UI
Commands
Command Bus
Command
Command Handler
Domain Model
Domain Model
Domain Model
Repository
Event Store
Aggregates
Events
Event Bus Event Handler
Data
Thin Data Layer
Query DTO
Events Use an autoincrement
column?
Use a ‘DossierNumberGenerator’
DossierNumberGenerator
_highestNumber = 01. GenerateNext
2. DossierNumberGeneratedEvent
3. onDossierNumberGenerated_highestNumber ++;
DossierNumberGenerator
_highestNumber = 0
onDossierNumberGenerated_highestNumber ++;
DossierNumberGeneratedEvent
DossierNumberGeneratedEvent
DossierNumberGeneratedEvent
Replay
Repository.GetById<DossierNumberGenerator>(id);
Problem 2
DomainEvent
Id
EventProviderId
Version
Raised
repo.GetById<EventProvider>(eventproviderId);
Get events based on type, not on eventproviderId?
Migrate those events
WIP
AnotherNewRefactoredAggregate
ANewRefactoredAggregate
anAggregate
SomeEvent
SomeOtherEvent
AndSomeMoreEvent
Migration Process
SomeEvent
SomeOtherEvent
AndSomeMoreEvent
AndAFunkyEvent
https://github.com/vermegi/Eventstream.Migratorhttps://github.com/NEventStore/NEventStore.Migrations
Event Store Event Store
Read the entire event stream Save the entire event stream
UI
Commands
Command Bus
Command
Command Handler
Domain Model
Domain Model
Domain Model
Repository
Event Store
Aggregates
Events
Event Bus Event Handler
Data
Thin Data Layer
Query DTO
Events
Replay needed!
Event Versioning with an EventUpdater
AnAggregate
_somePrivateStuff = 0
onSomeEvent:_somePriveStuff = somevalue;
SomeEvent
AnotherEvent
AndAnotherEvent
Replay
Repository.GetById<AnAggregate>(aggregateId);
SomeEvent
AnotherEvent
AndAnotherEvent
Update
Repository.GetById<AnAggregate>(aggregateId);
SomeUpdatedEvent
AnotherEvent
AndAnotherEvent
AndAnotherEvent
Problem 3
AnAggregateSnapshot
Repository.GetById<AnAggregate>(aggregateId);
_version = 666
SomeEventVersion = 667
AnotherEventVersion = 668
AndAnotherEventVersion = 669
AnAggregate
_somePrivateStuff = 0
onSomeEvent:_somePriveStuff = somevalue;
Replay
Problem 4
Hard to use in debugging
Hard to do data updates
Hard to query
Problem 5
AnAggregate
_somePrivateValue = 0DoSomething
onSomethingHappened_somePrivateValue = something;
DoSomething
SomethingHappenedEvent
WIPhttps://github.com/vermegi/ReplayDomain
UI
Commands
Command Bus
Command
Command Handler
Domain Model
Domain Model
Domain Model
Repository
Event Store
Aggregates
Events
Event Bus Event Handler
Data
Thin Data Layer
Query DTO
Events
Hard to do data updates
Reuse the same logic
Do it functional
Problem 6
And for the good news?
Some final thoughts ...
Thank you!