-
Notifications
You must be signed in to change notification settings - Fork 39
Getting started
Getting started with Cirqus is really easy. Cirqus has a fluent configuration API with a lot of options, but most of them are optional. Cirqus is designed to be used in domain driven designed projects, so if you know your way around in DDD, you'll find Cirqus easy to understand.
Cirqus works with command objects which are processed by a command processor. The command objects contain instructions to do something with an aggregate root. A command usually calls methods on that root or creates a new one. The aggregate root then emits events which are stored in the event store.
Before an action can be applied, the aggregate root has to be constructed. Cirqus creates a new object and then replays all previous events on that aggregate root.
The other part of CQRS is querying data. It's not recommended to just load an aggregate root. With this approach, you'd have to wait before the aggregate root is hydrated (a new object is created and all events are replayed on this object).
Cirqus has a concept of views and view managers to tackle this problem. A view is literally a view of your aggregate root. It can even contain information from multiple roots or just contain a part of the information.
When you start up your application, another thread with an event dispatcher is also started. The event dispatcher checks your event store frequently and dispatches new events to view managers. View managers are responsible for storing your views and updating them when necessary. You can have one view manager storing everything in a SQL Server database while another stores everything in MongoDB.
The events the view manager receives are applied on the view contained in that specific view manager. You can decide which events go to which views and how they are handled within that view.
If you're developing a booking system for hotels, some of your aggregate roots are probably a customer, a room and a booking. Maybe you'd like to keep track of bookings per room so you can quickly see which rooms are popular and which aren't.
In this case, you'd have a command that creates new bookings. The command needs information about the customer (usually an ID), the rooms (probably also IDs) which are being booked and some metadata about the booking itself like the check-in and check-out dates.
To create a new booking, you'd create a new instance of the mentioned command and give it to the command processor. The command processor then created a new booking instance and starts calling methods on that new instance.
Each and every one of those methods emits and event to say something's changed, nothing else. These methods don't actually change or update anything in the booking object. There will be an event that says the metadata (or parts of it) has changed (like the check-in date). There will probably also be an event that says that a room is added to the booking.
Next time a command needs to do something with the booking you just created, all the events from the previous paragraph will be applied on a new booking object. This means you'll have to create a method on the booking class that accepts the events you just emitted as parameter and knows how to handle them (e.g. update some properties).
Those events are stored in the event store. But what if you want to pull some statistics on the most popular rooms? Which rooms get booked more often and which rooms aren't popular at all?
To make this happen, you create a view. This view is configured to receive the events where a room is added or removed from a booking. Now each time such an event is added to the event store, the event dispatcher picks it up and sends this to your view which then handles the event. The event should contain information about the room which was added or removed from a booking. That allows you to update your view with information about which rooms are booked more often than others
Don't worry, the sidebar contains a lot of documentation!