I've been learning about CQRS/ES. Looking at small example projects I often see events mutating the entity state. For instance If we look at the Order
aggregate root:
public class Order : AggregateRoot {
private void Apply(OrderLineAddedEvent @event) {
var existingLine = this.OrderLines.FirstOrDefault(
i => i.ProductId == @event.ProductId);
if(existingLine != null) {
existingLine.AddToQuantity(@event.Quantity);
return;
}
this.OrderLines.Add(new OrderLine(@event.ProductId, @event.ProductTitle, @event.PricePerUnit, @event.Quantity));
}
public ICollection<OrderLine> OrderLines { get; private set; }
public void AddOrderLine(/*parameters*/) {
this.Apply(new OrderLineAddedEvent(/*parameters*/));
}
public Order() {
this.OrderLines = new List<OrderLine>();
}
public Order(IEnumerable<IEvent> history) {
foreach(IEvent @event in history) {
this.ApplyChange(@event, false);
}
}
}
public abstract class AggregateRoot {
public Queue<IEvent> UncommittedEvents { get; protected set; }
protected abstract void Apply(IEvent @event);
public void CommitEvents() {
this.UncommittedEvents.Clear();
}
protected void ApplyChange(IEvent @event, Boolean isNew) {
Apply(@event);
if(isNew) this.UncommittedEvents.Enqueue(@event);
}
}
when OrderLineAddedEvent
is applied it mutates Order
by adding new order line. But I don't understand these things:
- if it is a right approach how then the changes made are persisted?
- Or should I publish the event somehow to a corresponding handler from
Order
? How do I implement this technically? Should I use a service bus to transmit events?
UncommitedEvents
and persist them in an event store. – Mall