Navigation Menu

Skip to content

Instantly share code, notes, and snippets.

@dcomartin

dcomartin/ar.cs Secret

Created March 9, 2022 22:35
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save dcomartin/fa520537e9514d90f57581c4822c15a5 to your computer and use it in GitHub Desktop.
Save dcomartin/fa520537e9514d90f57581c4822c15a5 to your computer and use it in GitHub Desktop.
public class ShipmentAggregateRoot
{
private readonly SortedList<int, Stop> _stops = new();
private readonly List<IEvent> _events = new();
private ShipmentAggregateRoot(IReadOnlyList<Stop> stops)
{
for(var x = 0; x < stops.Count; x++)
{
_stops.Add(x, stops[x]);
}
}
public static ShipmentAggregateRoot Factory(PickupStop pickup, DeliveryStop delivery)
{
return new ShipmentAggregateRoot(new Stop[] { pickup, delivery });
}
public static ShipmentAggregateRoot Factory(Stop[] stops)
{
if (stops.Length < 2)
{
throw new InvalidOperationException("Shipment requires at least 2 stops.");
}
if (stops.First() is not PickupStop)
{
throw new InvalidOperationException("First stop must be a Pickup");
}
if (stops.Last() is not DeliveryStop)
{
throw new InvalidOperationException("first stop must be a Pickup");
}
return new ShipmentAggregateRoot(stops);
}
public List<IEvent> GetUncommittedEvents()
{
var evnts = new List<IEvent>(_events);
_events.Clear();
return evnts;
}
public void Arrive(int stopId, DateTime arrived)
{
var currentStop = _stops.SingleOrDefault(x => x.Value.StopId == stopId);
if (currentStop.Value == null)
{
throw new InvalidOperationException("Stop does not exist.");
}
var previousStopsAreNotDeparted = _stops.Any(x => x.Key < currentStop.Key && x.Value.Status != StopStatus.Departed);
if (previousStopsAreNotDeparted)
{
throw new InvalidOperationException("Previous stops have not departed.");
}
currentStop.Value.Arrive(arrived);
_events.Add(new Arrived(stopId, arrived));
var arrivedToScheduled = arrived - currentStop.Value.Scheduled;
if (arrivedToScheduled.TotalHours > 0)
{
_events.Add(new ArrivedLate(stopId, arrivedToScheduled));
}
}
public void Pickup(int stopId, DateTime departed)
{
var currentStop = _stops.SingleOrDefault(x => x.Value.StopId == stopId);
if (currentStop.Value == null)
{
throw new InvalidOperationException("Stop does not exist.");
}
if (currentStop.Value is not PickupStop)
{
throw new InvalidOperationException("Stop is not a pickup.");
}
if (currentStop.Value.Status != StopStatus.Arrived)
{
Arrive(stopId, departed);
}
currentStop.Value.Depart(departed);
_events.Add(new PickedUp(stopId, departed));
}
public void Deliver(int stopId, DateTime departed)
{
var currentStop = _stops.SingleOrDefault(x => x.Value.StopId == stopId);
if (currentStop.Value == null)
{
throw new InvalidOperationException("Stop does not exist.");
}
if (currentStop.Value is not DeliveryStop)
{
throw new InvalidOperationException("Stop is not a delivery.");
}
if (currentStop.Value.Status != StopStatus.Arrived)
{
Arrive(stopId, departed);
}
currentStop.Value.Depart(departed);
_events.Add(new Delivered(stopId, departed));
}
public bool IsComplete()
{
return _stops.All(x => x.Value.Status == StopStatus.Departed);
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment