5. Query and command sides
http://www.gridshore.nl/2009/12/21/cqrs-made-easy-with-cqrs4j
6. Event sourcing
● The single source of truth
● Capture all changes to an application state
as a sequence of events
● Metaphor -- a version control system
13. Code: command
https://github.com/gregoryyoung/m-r.git
public class DeactivateInventoryItem : Command {
public readonly Guid InventoryItemId;
public readonly int OriginalVersion;
public DeactivateInventoryItem(Guid inventoryItemId, int originalVersion)
{
InventoryItemId = inventoryItemId;
OriginalVersion = originalVersion;
}
}
14. Code: event
public class InventoryItemDeactivated : Event {
public readonly Guid Id;
public InventoryItemDeactivated(Guid id)
{
Id = id;
}
}
15. Code: controller
public class HomeController : Controller
{
private FakeBus _bus;
...
public ActionResult Deactivate(Guid id, int version)
{
_bus.Send(new DeactivateInventoryItem(id, version));
return RedirectToAction("Index");
}
16. Code: command handler
public class InventoryCommandHandlers
{
private readonly IRepository<InventoryItem> _repository;
...
public void Handle(DeactivateInventoryItem message)
{
// Construct item from stream of events
var item = _repository.GetById(message.InventoryItemId);
item.Deactivate();
_repository.Save(item, message.OriginalVersion);
}
17. Code: write model
public class InventoryItem : AggregateRoot
{
public void Deactivate()
{
if(!_activated)
throw new InvalidOperationException("already deactivated");
ApplyChange(new InventoryItemDeactivated(_id));
}
private void Apply(InventoryItemDeactivated e)
{
_activated = false;
}
18. Code: read model
public class InventoryListView : Handles<InventoryItemCreated>,
Handles<InventoryItemRenamed>, Handles<InventoryItemDeactivated>
{
....
public void Handle(InventoryItemDeactivated message)
{
BullShitDatabase.list.RemoveAll(x => x.Id == message.Id);
}
}
19. Code: controller
public class HomeController : Controller
{
private ReadModelFacade _readmodel;
...
public ActionResult Details(Guid id)
{
ViewData.Model = _readmodel.GetInventoryItemDetails(id);
return View();
}
20. Polyglot programming
● Javascript vs <you name it>
● Static typing for the command side vs
dynamic typing for the query side
● Core team vs outsourcers ;)
21. Top level architecture
● Don't do It. Just don't
● CQRS frameworks push you toward the anti-
pattern
22. Benefits of CQRS/ES
● handling complexity
● high-performance handling
● integrating with third party systems
● [ES] new reports from the historical data
● [ES] behavioral analysis