Skip to content

Instantly share code, notes, and snippets.

@JoeStead
Created August 23, 2016 13:02
Show Gist options
  • Save JoeStead/f68e94ba0cb378a07fb9fef5aa09338f to your computer and use it in GitHub Desktop.
Save JoeStead/f68e94ba0cb378a07fb9fef5aa09338f to your computer and use it in GitHub Desktop.
using System;
using System.Collections.Generic;
class Program
{
static void Main(string[] args)
{
var order = new Order(Guid.NewGuid(), Guid.NewGuid());
}
}
class Order : Aggregate<Order>
{
static Order()
{
Given<OrderStarted>((x, e) =>
{
x.Id = e.Id;
x.customerId = e.CustomerId;
x.status = OrderStatus.Open;
x.tickets = new List<Ticket>();
});
Given<TicketsReserved>((x, e) =>
{
var ticket = new Ticket(e.TicketId, e.Quantity);
x.status = OrderStatus.Reserved;
x.tickets.Add(ticket);
x.outstandingBalance += e.TicketPrice * e.Quantity;
});
Given<PaymentReceived>((x, e) =>
{
x.outstandingBalance -= e.Amount;
x.status = OrderStatus.Closed;
});
}
private Guid customerId;
private OrderStatus status;
private List<Ticket> tickets;
private decimal outstandingBalance;
public Order(Guid id, Guid customerId)
{
Then(new OrderStarted(id, customerId));
}
public void When(ReserveTickets command)
{
Then(new TicketsReserved(command.TicketId, command.Quantity, 25));
}
public void When(MakePayment command)
{
Then(new PaymentReceived(123));
}
}
struct Ticket
{
public Ticket(Guid ticketId, int quantity)
{
TicketId = ticketId;
Quantity = quantity;
}
public Guid TicketId { get; }
public int Quantity { get; }
}
enum OrderStatus
{
Open,
Reserved,
Closed
}
abstract class Aggregate<T> where T : Aggregate<T>
{
public Guid Id { get; protected set; }
private static readonly Dictionary<Type, object> _eventMappings = new Dictionary<Type, object>();
protected static void Given<TEvent>(Action<T, TEvent> action) where TEvent : class
{
_eventMappings.Add(typeof(TEvent), action);
}
protected void Then<TEvent>(TEvent e) where TEvent : class
{
((Action<T, TEvent>)_eventMappings[typeof(TEvent)])((T)this, e);
}
}
class ReserveTickets
{
public ReserveTickets(Guid ticketId, int quantity)
{
TicketId = ticketId;
Quantity = quantity;
}
public Guid TicketId { get; }
public int Quantity { get; }
}
class MakePayment
{
public MakePayment(string paymentToken)
{
PaymentToken = paymentToken;
}
public string PaymentToken { get; }
}
class OrderStarted
{
public OrderStarted(Guid id, Guid customerId)
{
Id = id;
CustomerId = customerId;
}
public Guid Id { get; }
public Guid CustomerId { get; }
}
class TicketsReserved
{
public TicketsReserved(Guid ticketId, int quantity, decimal ticketPrice)
{
TicketId = ticketId;
Quantity = quantity;
TicketPrice = ticketPrice;
}
public Guid TicketId { get; }
public int Quantity { get; }
public decimal TicketPrice { get; }
}
class PaymentReceived
{
public PaymentReceived(decimal amount)
{
Amount = amount;
}
public decimal Amount { get; }
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment