This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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