Skip to content

Instantly share code, notes, and snippets.

@dcomartin
Last active October 1, 2021 19:56
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/3c30de8883e7d50120405ce30b856be0 to your computer and use it in GitHub Desktop.
Save dcomartin/3c30de8883e7d50120405ce30b856be0 to your computer and use it in GitHub Desktop.
public class ShipmentAggregateRoot
{
private SortedList<int, Stop> Stops { get; } = 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("Last stop must be a Delivery");
}
return new ShipmentAggregateRoot(stops);
}
public void Arrive(int stopId)
{
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();
}
public void Pickup(int stopId)
{
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.");
}
currentStop.Value.Depart();
}
public void Deliver(int stopId)
{
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.");
}
currentStop.Value.Depart();
}
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