I det forrige indlæg så hvordan vi kunne kode en Beetroot
, som vi kunne sende en SqueezeCommand
til. Når command’en blev processeret ville den kalde Squeeze(howMuch)
-funktionen på rødbeden, som så ville emitte en BeetrootSquashed
event hvis den stadig havde list saft i sig, og ellers ville den emitte en BeetrootCompletelyCrushed
– så langt så godt!
Men vi mangler stadigvæk at få bragt lidt liv i det hele, og det er det vi skal kigge på i dette indlæg.
Command-processering
Udgangspunktet for alt hvad der sker i et Cirqus-baseret system er, at vi skal have fat i noget, der kan processere vores commands – og det er ikke så svært at få fat i sådan en, for du kan bare gøre sådan her:
var commandProcessor = new CommandProcessor(...);
hvor ...
skal udfyldes med 3 afhængigheder:
IEventStore
: En implementation af noget, der kan gemme og hente events (kan p.t. gøres i SQL Server, MongoDB og PostgreSQL)IAggregateRootRepository
: En implementation af noget, der kan hjælpe med at hydrere aggregate roots (findes p.t. kun i en “naiv” variant: En, der laver fuld hydrering hver gang der er behov)IEventDispatcher
: En implementation af noget, der gerne vil have mulighed for at arbejde videre på events i takt med at de bliver genereret (f.eks. til views/projektioner, integration til andre systemer, osv.)
Lad os starte med at bruge SQL Server som event store – det kan vi gøre sådan her:
var eventStore = new MsSqlEventStore("mssql", "Events", automaticallyCreateSchema: true);
forudsat at vi har en connection string i vores app.config
med navnet “mssql”. Vores aggregate root repository hedder DefaultAggregateRootRepository
og kræver et IEventStore
for at kunne fungere (fordi den skal hydrere aggregate roots på baggrund af events):
var aggregateRootRepository = new DefaultAggregateRootRepository(eventStore);
Afslutningsvis skal vi stille med en IEventDispatcher
, og der tager vi fat i en, der senere kan benyttes til at generere view-delen af vores system – den kræver et aggregate root repository fordi views skal kunne loade aggregate roots hvis de har brug for det:
var eventDispatcher = new ViewManagerEventDispatcher(aggregateRootRepository);
Hvis man sætter det sammen, så ser det således ud:
// ved opstart: var eventStore = new MsSqlEventStore("mssql", "Events", automaticallyCreateSchema: true); var repository = new DefaultAggregateRootRepository(eventStore); var dispatcher = new ViewManagerEventDispatcher(aggregateRootRepository); var commandProcessor = new CommandProcessor(eventStore, repository, dispatcher); // først.... commandProcessor.Initialize(); // og så i resten af applikationens levetid: commandProcessor.ProcessCommand(...);
og det er faktisk alt, hvad der skal til for at kunne komme i gang med at kode en rig domænemodel baseret på event sourcing – ikke så ringe, hvis du spørger mig 🙂
I næste indlæg vil vi kigge på hvordan man kan etablere en projektion af vores events: Et view, som holdes opdateret med events efterhånden som de bliver genereret. Stay tuned….