Skip to content

Instantly share code, notes, and snippets.

@dcomartin

dcomartin/es.cs Secret

Created September 9, 2021 21:16
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
Star You must be signed in to star a gist
Save dcomartin/827f281d26cc880ad7abafc2e17e287f to your computer and use it in GitHub Desktop.
using System;
using System.Collections.Generic;
using System.Linq;
namespace Demo.EventSourced
{
public class ShipmentAggregateRoot
{
private readonly ShipmentState _projection = new();
public void Dispatch(int shipmentId, IEnumerable<ShipmentStop> stops)
{
var dispatched = new Dispatched(shipmentId, stops, DateTime.UtcNow);
Apply(dispatched);
}
private void Apply(Dispatched dispatched)
{
_projection.Stops = dispatched.Stops.OrderBy(x => x.Sequence).Select(x => new StopState(x.StopId, x.StopType, StopStatus.InTransit)).ToList();
_projection.CurrentStopState = _projection.Stops.First();
}
public void Arrive(int stopId)
{
if (IsComplete())
{
throw new InvalidOperationException("Shipment is already complete.");
}
if (_projection.CurrentStopState.StopId != stopId)
{
throw new InvalidOperationException("Stop does not exist or is not the current stop.");
}
if (_projection.CurrentStopState.Status != StopStatus.InTransit)
{
throw new InvalidOperationException("Stop has already arrived.");
}
var arrived = new Arrived(stopId, DateTime.UtcNow);
Apply(arrived);
}
private void Apply(Arrived arrived)
{
_projection.CurrentStopState.Status = StopStatus.Arrived;
}
public void Pickup(int stopId)
{
if (IsComplete())
{
throw new InvalidOperationException("Shipment is already complete.");
}
if (_projection.CurrentStopState.StopId != stopId)
{
throw new InvalidOperationException("Stop does not exist or is not the current stop.");
}
if (_projection.CurrentStopState.Type != StopType.Pickup)
{
throw new InvalidOperationException("Stop is not a pickup.");
}
if (_projection.CurrentStopState.Status == StopStatus.Departed)
{
throw new InvalidOperationException("Stop has already departed.");
}
if (_projection.CurrentStopState.Status == StopStatus.InTransit)
{
throw new InvalidOperationException("Stop hasn't arrived yet.");
}
var pickedUp = new PickedUp(stopId, DateTime.UtcNow);
Apply(pickedUp);
}
private void Apply(PickedUp pickedUp)
{
_projection.CurrentStopState = _projection.Stops.SkipWhile(x => x.Status != StopStatus.InTransit).FirstOrDefault();
}
public void Deliver(int stopId)
{
if (IsComplete())
{
throw new InvalidOperationException("Shipment is already complete.");
}
if (_projection.CurrentStopState.StopId != stopId)
{
throw new InvalidOperationException("Stop does not exist or is not the current stop.");
}
if (_projection.CurrentStopState.Type != StopType.Delivery)
{
throw new InvalidOperationException("Stop is not a delivery.");
}
if (_projection.CurrentStopState.Status == StopStatus.Departed)
{
throw new InvalidOperationException("Stop has already departed.");
}
if (_projection.CurrentStopState.Status == StopStatus.InTransit)
{
throw new InvalidOperationException("Stop hasn't arrived yet.");
}
var delivered = new Delivered(stopId, DateTime.UtcNow);
Apply(delivered);
}
private void Apply(Delivered delivered)
{
_projection.CurrentStopState = _projection.Stops.SkipWhile(x => x.Status != StopStatus.InTransit).FirstOrDefault();
}
public bool IsComplete()
{
return _projection.CurrentStopState == null;
}
}
public record ShipmentStop(int StopId, StopType StopType, int Sequence);
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment