namespace SimpleCQRS { public interface IReadModelFacade { IEnumerable<InventoryItemListDto> GetInventoryItems(); InventoryItemDetailsDto GetInventoryItemDetails(Guid id); } public class InventoryItemDetailsDto { public Guid Id; public string Name; public int CurrentCount; public int Version; public InventoryItemDetailsDto(Guid id, string name, int currentCount, int version) { Id = id; Name = name; CurrentCount = currentCount; Version = version; } } public class InventoryItemListDto { public Guid Id; public string Name; public InventoryItemListDto(Guid id, string name) { Id = id; Name = name; } } public class InventoryListView : Handles<InventoryItemCreated>, Handles<InventoryItemRenamed>, Handles<InventoryItemDeactivated> { public void Handle(InventoryItemCreated message) { FakeDatabase.list.Add(new InventoryItemListDto(message.Id, message.Name)); } public void Handle(InventoryItemRenamed message) { var item = FakeDatabase.list.Single(x => x.Id == message.Id); item.Name = message.NewName; } public void Handle(InventoryItemDeactivated message) { FakeDatabase.list.RemoveAll(x => x.Id == message.Id); } } public class InventoryItemDetailView : Handles<InventoryItemCreated>, Handles<InventoryItemDeactivated>, Handles<InventoryItemRenamed>, Handles<ItemsRemovedFromInventory>, Handles<ItemsCheckedInToInventory> { public void Handle(InventoryItemCreated message) { FakeDatabase.details.Add(message.Id, new InventoryItemDetailsDto(message.Id, message.Name, 0, 0)); } public void Handle(InventoryItemRenamed message) { InventoryItemDetailsDto d = GetDetailsItem(message.Id); d.Name = message.NewName; d.Version = message.Version; } private InventoryItemDetailsDto GetDetailsItem(Guid id) { InventoryItemDetailsDto d; if (!FakeDatabase.details.TryGetValue(id, out d)) { throw new InvalidOperationException("did not find the original inventory this shouldnt happen"); } return d; } public void Handle(ItemsRemovedFromInventory message) { InventoryItemDetailsDto d = GetDetailsItem(message.Id); d.CurrentCount -= message.Count; d.Version = message.Version; } public void Handle(ItemsCheckedInToInventory message) { InventoryItemDetailsDto d = GetDetailsItem(message.Id); d.CurrentCount += message.Count; d.Version = message.Version; } public void Handle(InventoryItemDeactivated message) { FakeDatabase.details.Remove(message.Id); } } public class ReadModelFacade : IReadModelFacade { public IEnumerable<InventoryItemListDto> GetInventoryItems() { return FakeDatabase.list; } public InventoryItemDetailsDto GetInventoryItemDetails(Guid id) { return FakeDatabase.details[id]; } } internal class FakeDatabase { public static Dictionary<Guid, InventoryItemDetailsDto> details = new(); public static List<InventoryItemListDto> list = new(); } }