Event Sourcing Cameron Fletcher Agenda What is an Event? Events as a Storage Mechanism Versioning Testing with Events Performance and Scalability Demonstration What is an Event? An Event An event is something that has happened in the past as a result of a change in state of our domain Fill glass Request to change state Glass has been filled Event Glass is already full! Glass is broken! Exception Events as a Storage Mechanism Shopping Cart Created Item Added Carts Item Added CartId HasCheckedOut 1 True False Item Added CartItems Checkout Completed CartId ItemId Name 1 1 Domain Driven Design 1 2 Enterprise Integration Patterns 1 3 Event Centric Shopping Cart Created Item Added Item Added Item Added Checkout Completed Domain Object Shopping Cart Created Item Added Item Added Item Added Item Removed Checkout Completed Versioning 7 6 5 4 3 2 1 snapshot Cart Domain Object Example // request to mutate state public void Add(Item item) { if (this.itemCount > 5) throw new CartFullException(this.id); ApplyChange( new ItemAdded(this.id, item.Name)); } // mutate state private void Apply(ItemAdded @event) { this.itemCount++; } Domain Object Base protected void ApplyChange(Event @event) { this.ApplyChange(@event, true); } private void ApplyChange(Event @event, bool isNew) { this.AsDynamic().Apply(@event); if (isNew) this.uncommittedChanges.Add(@event); } Domain Object Reconstitution public void LoadFromHistory(IEnumerable<Event> history) { foreach (var @event in history) this.ApplyChange(@event, false); } Domain Object Persistence public IEnumerable<Event> GetUncommittedChanges() { return this.uncommittedChanges; } public void MarkChangesAsCommitted() { this.uncommittedChanges.Clear(); } Testing with Events Overdraw Attempts are Rejected Given An account with a balance of 100 When A debit is requested for 101 Then An InsufficientBalanceException is thrown Overdraw Attempts are Rejected Given An account is created A deposit was made for 100 When A debit is requested for 101 Then An InsufficientBalanceException is thrown Overdraw Attempts are Rejected Given A series of events When A command Then Zero or more events, or an exception is thrown Overdraw Attempts are Rejected Given An account is created A deposit was made for 100 A debit is requested for 101 When A debit is requested for 20 Then An InsufficientBalanceException is thrown Performance and Scalability Performance and Scalability Benefits Append-only model Partitioning (Sharding) Persisting Objects Reconstituting Objects Demonstration Summary Questions?