Skip to content

Instantly share code, notes, and snippets.

@nbarnwell
Created February 3, 2016 16:49
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save nbarnwell/fadee72c0753ea1f49dc to your computer and use it in GitHub Desktop.
Save nbarnwell/fadee72c0753ea1f49dc to your computer and use it in GitHub Desktop.
public interface Event
{
public Guid Id;
public Guid CausationId;
public CorrelationId;
public Guid [AggregateName]Id;
public int Version;
}
public abstract class AggregateRoot
{
private readonly IList<Event> _events = ...;
public Guid Id { get; private set; }
private void Record(Event evt)
{
_events.Add(evt);
}
public IEnumerable<Event> GetEvents()
{
return _events;
}
}
public class SalesOrder : AggregateRoot
{
public void Create(Guid id, string reference)
{
Record(new OrderCreated(id, reference));
}
private void Apply(OrderCreated evt)
{
Id = id;
}
public void PlaceOrder()
{
if (_cancelled)
{
throw new DomainException("Can't cancel an order that's alredy been placed.");
}
Record(new OrderPlaced(Id));
}
public void CancelOrder()
{
Record(new OrderCancelled(Id));
}
private void Apply(OrderCancelled evt)
{
_cancelled = true;
}
}
public class CreateOrderHandler
: ICommandHandler<CreateOrder>
{
public void Handle(CreateOrder command)
{
var o = new SalesOrder();
o.Create(Guid.NewId(), command.Reference);
var events = o.GetEvents();
_repo.Save(o);
_bus.Publish(events);
}
}
public interface IRepository<T>
{
void Add(T item);
T Get(Guid id);
}
public class Repository<T> : IRepo<T>
{
public void Add(T item)
{
_eventStore.Save(item.Id, item.GetEvents());
item.AcceptEvents();
}
public T Get(Guid id)
{
var events = _eventStore.Load(id);
var item = new T();
foreach (var e in events)
{
item.Apply(e);
}
return item;
}
}
public class OrderCreatedHandler
: IEventHandler<OrderCreated>
{
public void Handle(OrderCreated evt)
{
GetConnection().Execute(
@"insert into SalesOrder
(Id, Version) values (@Id, @Version);",
evt);
}
}
public class OrderCancelledHandler
: IEH<OrderCancelled>
{
public void Handle(OP evt)
{
var rowsUpdated = GetConnection.Execute(
@"update SalesOrder
set
Cancelled = 1,
Version = @Version
where
Id = @Id
and Version = @Version;",
evt);
if (rowsUpdated != 1)
{
var version = c.ExecScalar("select version from so where Id = @Id");
if (version >= evt.Version)
{
return;
}
_bus.SendToBackOfQueue(evt);
// OR
_delayService.Hold(evt, TimeSpan.FromSeconds(10));
// OR
var missing =
_eventStore.GetEventsSince(
evt.AggregateId,
version);
foreach (var missingEvent in missing)
{
_bus.SendToSelf(missingEvent);
}
_bus.SendToSelf(evt);
}
}
}
public class OrderPlacedHandler
: IEH<OrderPlaced>
{
public void Handle(OP evt)
{
GetConnection.Execute(
@"update SalesOrder
set Placed = 1
Version = @Version
where Id = @Id;",
evt);
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment