Mixter is a project to discover CQRS/Event sourcing through koans in multiple languages.
At this point the koans have been ported to 4 languages: C#, Java 8, PHP and Javascript.
Checkout slide
branch, where you can find slides used for Mix-IT workshop.
It explains the main steps and goals for each (only the title is in French ;)).
- Choose a language and checkout
{language}-workshop
, forjava
that would bejava-workshop
. - Implement the failing test
- merge and implement the next test :
{language}-test-{step}.{test number}
[1]
[1] to see the list of available tags you can use git tag -l | grep {language}
If you somehow get lost or stuck, you can git merge {language}-solution-{step}
or git checkout {language}-solution-{step}
and see what our solution looks like.
Feel free to use issues in this repo to give your feedback, to propose some improvements, to ask for other languages...and even better to submit pull requests.
We have done some choices that we consider implementation details, but that can hurt some people. So we try to explain them here.
-
use an AggregateRoot base class that accumulate uncommitted events that are picked by Repository on Save of the aggregate.
-
use DomainEvents.Raise(event) static call from AggregateRoot protected Apply method
We chose a third way that consists of passing an IEventPublisher (with Publish method) to each aggregate method to raise events. There is no more need to call Repository.Save and it avoids static method call.
We thought this "transient state" as a special projection (like Read model ones) to take further decision in the aggregate, that's why we call it DecisionProjection. We kept this class private inside the aggregate.
Commands and command handlers are not shown here for now, for simplicity, it has been left implicit through method of aggregates.
Perhaps something to introduce in further version.
You can contact us through GitHub or on Twitter : @clem_bouillier, @florentpellet, @jeanhelou, @ouarzy.