Command Query Responsibility Segregation and Event Sourcing

Uploaded on

Presentation for a coffee'n'code meeting in Donetsk

Presentation for a coffee'n'code meeting in Donetsk

More in: Technology
  • Full Name Full Name Comment goes here.
    Are you sure you want to
    Your message goes here
    Be the first to comment
No Downloads


Total Views
On Slideshare
From Embeds
Number of Embeds



Embeds 0

No embeds

Report content

Flagged as inappropriate Flag as inappropriate
Flag as inappropriate

Select your reason for flagging this presentation as inappropriate.

    No notes for slide


  • 1. CommandQueryResponsibilitySegregation andEvent SourcingCQRS/ESMitin 2012
  • 2. Authors Greg Young Udi Dahan
  • 3. Preface1. Probably you dont need CQRS/ES2. Do not consider CQRS to be a top-level architectural pattern
  • 4. Driving forces1. Collaboration2. Staleness
  • 5. Query and command sides
  • 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
  • 7. Event log facilities● Complete rebuild● Temporal query● Event replay
  • 8. Event Store● Simple event store consists of 78 lines of C#● Snapshots as performance optimization
  • 9. Persistence options● RDBMS● Aggregate-oriented database
  • 10. Validation● Validation● Business rules
  • 11. Asynchronous interface● Validation results are available immediately● Business rule output are delayed in time
  • 12. Capture users intentTask-based UI
  • 13. Code: command class DeactivateInventoryItem : Command { public readonly Guid InventoryItemId; public readonly int OriginalVersion; public DeactivateInventoryItem(Guid inventoryItemId, int originalVersion) { InventoryItemId = inventoryItemId; OriginalVersion = originalVersion; }}
  • 14. Code: eventpublic class InventoryItemDeactivated : Event { public readonly Guid Id; public InventoryItemDeactivated(Guid id) { Id = id; }}
  • 15. Code: controllerpublic 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 handlerpublic 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 modelpublic 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 modelpublic class InventoryListView : Handles<InventoryItemCreated>, Handles<InventoryItemRenamed>, Handles<InventoryItemDeactivated>{ .... public void Handle(InventoryItemDeactivated message) { BullShitDatabase.list.RemoveAll(x => x.Id == message.Id); }}
  • 19. Code: controllerpublic 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● Dont do It. Just dont● 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