-
-
Save dcomartin/9db8f9281a2f45a19d93ee469d63bd4c to your computer and use it in GitHub Desktop.
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
public class CurrentState | |
{ | |
public int QuantityOnHand { get; set; } | |
} | |
public class WarehouseProduct | |
{ | |
public string Sku { get; } | |
private readonly IList<IEvent> _allEvents = new List<IEvent>(); | |
private readonly IList<IEvent> _uncommittedEvents = new List<IEvent>(); | |
// Projection (Current State) | |
private readonly CurrentState _currentState = new(); | |
public WarehouseProduct(string sku) | |
{ | |
Sku = sku; | |
} | |
public void ShipProduct(int quantity) | |
{ | |
if (quantity > _currentState.QuantityOnHand) | |
{ | |
throw new InvalidDomainException("Ah... we don't have enough product to ship?"); | |
} | |
AddEvent(new ProductShipped(Sku, quantity, DateTime.UtcNow)); | |
} | |
public void ReceiveProduct(int quantity) | |
{ | |
AddEvent(new ProductReceived(Sku, quantity, DateTime.UtcNow)); | |
} | |
public void AdjustInventory(int quantity, string reason) | |
{ | |
if (_currentState.QuantityOnHand + quantity < 0) | |
{ | |
throw new InvalidDomainException("Cannot adjust to a negative quantity on hand."); | |
} | |
AddEvent(new InventoryAdjusted(Sku, quantity, reason, DateTime.UtcNow)); | |
} | |
private void Apply(ProductShipped evnt) | |
{ | |
_currentState.QuantityOnHand -= evnt.Quantity; | |
} | |
private void Apply(ProductReceived evnt) | |
{ | |
_currentState.QuantityOnHand += evnt.Quantity; | |
} | |
private void Apply(InventoryAdjusted evnt) | |
{ | |
_currentState.QuantityOnHand += evnt.Quantity; | |
} | |
public void ApplyEvent(IEvent evnt) | |
{ | |
switch (evnt) | |
{ | |
case ProductShipped shipProduct: | |
Apply(shipProduct); | |
break; | |
case ProductReceived receiveProduct: | |
Apply(receiveProduct); | |
break; | |
case InventoryAdjusted inventoryAdjusted: | |
Apply(inventoryAdjusted); | |
break; | |
default: | |
throw new InvalidOperationException("Unsupported Event."); | |
} | |
_allEvents.Add(evnt); | |
} | |
public void AddEvent(IEvent evnt) | |
{ | |
ApplyEvent(evnt); | |
_uncommittedEvents.Add(evnt); | |
} | |
public IList<IEvent> GetUncommittedEvents() | |
{ | |
return new List<IEvent>(_uncommittedEvents); | |
} | |
public IList<IEvent> GetAllEvents() | |
{ | |
return new List<IEvent>(_allEvents); | |
} | |
public void EventsCommitted() | |
{ | |
_uncommittedEvents.Clear(); | |
} | |
public int GetQuantityOnHand() | |
{ | |
return _currentState.QuantityOnHand; | |
} | |
} | |
public class InvalidDomainException : Exception | |
{ | |
public InvalidDomainException(string message) : base(message) | |
{ | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment