Skip to content

Instantly share code, notes, and snippets.

@dcomartin
Created February 22, 2024 22:36
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/6158f67ccf78b80612fad89a61779a50 to your computer and use it in GitHub Desktop.
Save dcomartin/6158f67ccf78b80612fad89a61779a50 to your computer and use it in GitHub Desktop.
public class WarehouseProduct
{
private readonly string _sku;
private readonly List<IEvent> _uncommittedEvents = new();
private int _quantityOnHand = 0;
public WarehouseProduct(string sku)
{
_sku = sku;
}
public void ShipProduct(int quantity)
{
if (quantity > _quantityOnHand)
{
throw new InvalidDomainException("Ah... we don't have enough product to ship?");
}
AddEvent(new ProductShipped(_sku, quantity, DateTime.UtcNow));
}
private void Apply(ProductShipped evnt)
{
_quantityOnHand -= evnt.Quantity;
}
public void ReceiveProduct(int quantity)
{
AddEvent(new ProductReceived(_sku, quantity, DateTime.UtcNow));
}
private void Apply(ProductReceived evnt)
{
_quantityOnHand += evnt.Quantity;
}
public void AdjustInventory(int quantity, string reason)
{
if (_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(InventoryAdjusted evnt)
{
_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.");
}
}
private void AddEvent(IEvent evnt)
{
ApplyEvent(evnt);
_uncommittedEvents.Add(evnt);
}
public IReadOnlyCollection<IEvent> Events() => _uncommittedEvents.AsReadOnly();
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment