Created
July 11, 2018 15:51
-
-
Save jen20/08c7ba865ef5dd95ff1a8c9d351f60ec to your computer and use it in GitHub Desktop.
This file contains hidden or 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.ComponentModel; | |
using System.Diagnostics; | |
namespace Messaging101 { | |
/* Create inventory bucket | |
* Check into inventory (quantity) | |
* Check out of inventory (quantity) | |
* throw Exception | |
*/ | |
public static class Program { | |
public interface Command {} | |
public class CheckItemOut : Command { | |
public readonly uint Quantity; | |
public CheckItemOut(uint quantity) { | |
Quantity = quantity; | |
} | |
} | |
public interface IHandle<in T> where T : Command { | |
void Handle(T message); | |
} | |
public class NarrowingHandler<T, V> : IHandle<T> where T : Command where V : T { | |
private IHandle<V> _next; | |
public NarrowingHandler(IHandle<V> next) { | |
_next = next; | |
} | |
public void Handle(T message) { | |
_next.Handle((V)message); | |
} | |
} | |
public class LoggingHandler<T> : IHandle<T> where T : Command { | |
private IHandle<T> _next; | |
public LoggingHandler(IHandle<T> next) { | |
_next = next; | |
} | |
public void Handle(T message) { | |
Console.WriteLine($"About to do command: {message.GetType()}"); | |
_next.Handle(message); | |
Console.WriteLine($"Finished doing command: {message.GetType()}"); | |
} | |
} | |
public class CheckItemOutHandler : IHandle<CheckItemOut> { | |
private static List<Event> _history = new List<Event> { | |
new ItemCheckedIn(100), | |
new ItemCheckedOut(50) | |
}; | |
public void Handle(CheckItemOut message) { | |
// Load object from history | |
var obj = new InventoryBucket(_history); | |
// Call CheckItemOut | |
obj.CheckItemOut(message.Quantity); | |
var producedEvents = obj.GetProducedEvents(); | |
if (producedEvents.Count > 0) { | |
_history.AddRange(producedEvents); | |
foreach (var e in producedEvents) { | |
Console.WriteLine("Produced: " + e); | |
} | |
} | |
} | |
} | |
public static void Main() { | |
var checkItemOutPipeline = | |
new LoggingHandler<CheckItemOut>( | |
new CheckItemOutHandler()); | |
checkItemOutPipeline.Handle(new CheckItemOut(10)); | |
// | |
// | |
// var bucket = new InventoryBucket(); | |
// bucket.CheckItemIn(100); | |
// bucket.CheckItemOut(10); | |
// bucket.CheckItemOut(10); | |
// bucket.CheckItemIn(100); | |
// | |
// var history = bucket.GetProducedEvents(); | |
// // Save in the database | |
// | |
// | |
// Debugger.Break(); | |
} | |
} | |
public class InventoryBucket { | |
private uint _quantityOnHand; | |
public override string ToString() { | |
return $"Inventory Item: Count: {_quantityOnHand}"; | |
} | |
private List<Event> _producedEvents = new List<Event>(); | |
public List<Event> GetProducedEvents() { | |
var toReturn = _producedEvents; | |
_producedEvents = new List<Event>(); | |
return toReturn; | |
} | |
private void RaiseEvent(Event @event) { | |
_producedEvents.Add(@event); | |
Apply(@event); | |
} | |
public InventoryBucket(List<Event> history) { | |
foreach (var @event in history) { | |
Apply(@event); | |
} | |
} | |
public InventoryBucket() {} | |
private void Apply(Event @event) { | |
switch (@event) | |
{ | |
case ItemCheckedIn e: | |
_quantityOnHand += e.Quantity; | |
break; | |
case ItemCheckedOut e: | |
_quantityOnHand -= e.Quantity; | |
break; | |
default: | |
throw new ArgumentException("wtf"); | |
} | |
} | |
public void CheckItemIn(uint quantity) { | |
if (quantity == 0) { | |
throw new ArgumentException("quantity"); | |
} | |
RaiseEvent(new ItemCheckedIn(quantity)); | |
} | |
public void CheckItemOut(uint quantity) { | |
if (quantity == 0) { | |
throw new ArgumentException("quantity"); | |
} | |
if (_quantityOnHand < quantity) { | |
throw new ArgumentException("quantity"); | |
} | |
RaiseEvent(new ItemCheckedOut(quantity)); | |
} | |
} | |
public interface Event { | |
} | |
public class ItemCheckedOut : Event { | |
public readonly uint Quantity; | |
public ItemCheckedOut(uint quantity) { | |
Quantity = quantity; | |
} | |
} | |
public class ItemCheckedIn : Event { | |
public readonly uint Quantity; | |
public ItemCheckedIn(uint quantity) { | |
Quantity = quantity; | |
} | |
} | |
public class InventoryBucketCreated : Event { | |
public readonly string ItemName; | |
public readonly uint OpeningCount; | |
public InventoryBucketCreated(string itemName, uint openingCount) { | |
ItemName = itemName; | |
OpeningCount = openingCount; | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment