Skip to content

Instantly share code, notes, and snippets.

@JoeStead
Created August 23, 2016 12:54
Show Gist options
  • Save JoeStead/48d18ecf991c058cef828ae63501a178 to your computer and use it in GitHub Desktop.
Save JoeStead/48d18ecf991c058cef828ae63501a178 to your computer and use it in GitHub Desktop.
using System;
using System.Collections.Generic;
using System.Diagnostics;
class Program
{
static void Main(string[] args)
{
var order = new Order(Guid.NewGuid(), Guid.NewGuid());
}
}
class Order : Aggregate
{
private Order()
{
Given<OrderStarted>(e =>
{
Id = e.Id;
customerId = e.CustomerId;
status = OrderStatus.Open;
tickets = new List<Ticket>();
});
Given<TicketsReserved>(e =>
{
var ticket = new Ticket(e.TicketId, e.Quantity);
status = OrderStatus.Reserved;
tickets.Add(ticket);
outstandingBalance += e.TicketPrice * e.Quantity;
});
Given<PaymentReceived>(e =>
{
outstandingBalance -= e.Amount;
status = OrderStatus.Closed;
});
}
private Guid customerId;
private OrderStatus status;
private List<Ticket> tickets;
private decimal outstandingBalance;
public Order(Guid id, Guid customerId) : this()
{
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
{
public Guid Id { get; protected set; }
private readonly Dictionary<Type, object> _eventMappings = new Dictionary<Type, object>();
protected void Given<TEvent>(Action<TEvent> action) where TEvent : class
{
_eventMappings.Add(typeof(TEvent), action);
}
protected void Then<TEvent>(TEvent e) where TEvent : class
{
((Action<TEvent>)_eventMappings[typeof(TEvent)])(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