Created
April 1, 2017 22:09
-
-
Save jasonmitchell/2edadbce2208e14dee1227a5ab3a1c6f to your computer and use it in GitHub Desktop.
Event Sourced Aggregates
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
using System; | |
using System.Collections.Generic; | |
namespace Aggregates | |
{ | |
public abstract class Aggregate : IAggregate | |
{ | |
private readonly Dictionary<Type, Action<object>> handlers = new Dictionary<Type, Action<object>>(); | |
private readonly Queue<object> uncommittedEvents = new Queue<object>(); | |
private int version; | |
public Guid Id { get; protected set; } | |
int IAggregate.Version => version; | |
IEnumerable<object> IAggregate.UncommittedEvents => uncommittedEvents; | |
IEnumerable<Type> IAggregate.EventTypes => handlers.Keys; | |
protected void Given<TEvent>(Action<TEvent> handler) | |
{ | |
handlers.Add(typeof(TEvent), x => handler((TEvent)x)); | |
} | |
protected void Then<TEvent>(TEvent e) | |
{ | |
((IAggregate)this).Apply(e); | |
uncommittedEvents.Enqueue(e); | |
} | |
void IAggregate.Apply(object e) | |
{ | |
handlers[e.GetType()](e); | |
version++; | |
} | |
void IAggregate.ClearEvents() | |
{ | |
uncommittedEvents.Clear(); | |
} | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
using System; | |
using System.Collections.Generic; | |
namespace Aggregates | |
{ | |
public interface IAggregate | |
{ | |
Guid Id { get; } | |
int Version { get; } | |
IEnumerable<object> UncommittedEvents { get; } | |
IEnumerable<Type> EventTypes { get; } | |
void Apply(object e); | |
void ClearEvents(); | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
using System; | |
using System.Collections.Generic; | |
using System.Collections.ObjectModel; | |
using System.Linq; | |
namespace Aggregates.Sales | |
{ | |
public class Order : Aggregate | |
{ | |
private ReadOnlyCollection<OrderItem> items; | |
private bool paid; | |
private bool delivered; | |
private decimal TotalValue => items.Sum(x => x.Price); | |
private Order() | |
{ | |
Given<OrderPlaced>(e => | |
{ | |
Id = e.Id; | |
items = new ReadOnlyCollection<OrderItem>(e.Items.Select(x => new OrderItem(x.ProductId, x.Price)).ToList()); | |
}); | |
Given<PaymentReceived>(e => paid = true); | |
Given<OrderDelivered>(e => delivered = true); | |
} | |
public Order(Guid id, List<OrderItem> items) : this() | |
{ | |
Then(new OrderPlaced(id, items.Select(x => new OrderPlaced.Item(x.ProductId, x.Price)).ToList())); | |
} | |
public void Pay() | |
{ | |
Then(new PaymentReceived(Id, TotalValue)); | |
} | |
public void DeliveredToRecipient() | |
{ | |
Then(new OrderDelivered(Id)); | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment