using System; using System.Collections.Generic; using SlimDomainModel; namespace EventSourcing.Demo.Slim { 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(); } }