using System.Collections.Generic;
public OrderEvent(string eventType, string orderReference, string orderPortfolioReference, decimal? amount = null, byte? direction = null)
OrderReference = orderReference;
OrderPortfolioReference = orderPortfolioReference;
Amount = (decimal)amount.Value;
Direction = (byte)direction.Value;
public Guid Id {get; set;}
public string OrderReference {get; set;}
public string OrderPortfolioReference {get; set;}
public string EventType {get; set;}
public decimal Amount{get; set;}
public byte Direction{get; set;}
public interface IOrderEvent
public Guid Id {get; set;}
public string OrderReference {get; set;}
public string OrderPortfolioReference {get; set;}
public class OrderEventBase : IOrderEvent
public OrderEventBase(OrderEvent orderEvent)
OrderReference = orderEvent.OrderReference;
OrderPortfolioReference = orderEvent.OrderPortfolioReference;
public Guid Id {get; set;}
public string OrderReference {get; set;}
public string OrderPortfolioReference {get; set;}
public class OrderEventReceived : OrderEventBase
public OrderEventReceived(OrderEvent orderEvent) : base(orderEvent)
Amount = orderEvent.Amount;
Direction = orderEvent.Direction;
public decimal Amount{get; set;}
public byte Direction{get; set;}
public class OrderEventCancelled : OrderEventBase
public OrderEventCancelled(OrderEvent orderEvent) : base(orderEvent)
public class OrderEventRejected : OrderEventBase
public OrderEventRejected(OrderEvent orderEvent) : base(orderEvent)
public class OrderEventFactory
public IOrderEvent GetOrderEvent(OrderEvent orderEvent)
if (orderEvent.EventType == nameof(OrderEventReceived))
return new OrderEventReceived(orderEvent);
if (orderEvent.EventType == nameof(OrderEventCancelled))
return new OrderEventCancelled(orderEvent);
if (orderEvent.EventType == nameof(OrderEventRejected))
return new OrderEventRejected(orderEvent);
throw new NotImplementedException($"The orderEvent type '{orderEvent}' is not implemented.");
public interface IOrderEventMaterialiser
public bool IsApplicable(OrderEvent orderEvent);
public void Materialise(IOrderEvent orderEvent);
public class OrderPendingAggregationMaterialiser : IOrderEventMaterialiser
public bool IsApplicable(OrderEvent orderEvent)
return orderEvent.EventType == nameof(OrderEventReceived);
public void Materialise(IOrderEvent orderEvent)
var orderEventReceived = orderEvent as OrderEventReceived;
Console.WriteLine("\n\t\tCreating new OrderPendingAggregation record");
Console.WriteLine($"\t\t{nameof(orderEventReceived.Id)}: {orderEventReceived.Id}");
Console.WriteLine($"\t\t{nameof(orderEventReceived.Amount)}: {orderEventReceived.Amount}");
Console.WriteLine($"\t\t{nameof(orderEventReceived.OrderReference)}: {orderEventReceived.OrderReference}");
Console.WriteLine($"\t\t{nameof(orderEventReceived.OrderPortfolioReference)}: {orderEventReceived.OrderPortfolioReference}");
Console.WriteLine($"\t\t{nameof(orderEventReceived.Direction)}: {orderEventReceived.Direction}");
public class OrderPendingAggregationCancellationMaterialiser : IOrderEventMaterialiser
public bool IsApplicable(OrderEvent orderEvent)
return orderEvent.EventType == nameof(OrderEventCancelled);
public void Materialise(IOrderEvent orderEvent)
var orderEventReceived = orderEvent as OrderEventCancelled;
Console.WriteLine("\n\t\tDeleting OrderPendingAggregation record, Cancelled sucessfully!");
Console.WriteLine($"\t\t{nameof(orderEventReceived.Id)}: {orderEventReceived.Id}");
Console.WriteLine($"\t\t{nameof(orderEventReceived.OrderReference)}: {orderEventReceived.OrderReference}");
Console.WriteLine($"\t\t{nameof(orderEventReceived.OrderPortfolioReference)}: {orderEventReceived.OrderPortfolioReference}");
public class OrderPendingAggregationRejectionMaterialiser : IOrderEventMaterialiser
public bool IsApplicable(OrderEvent orderEvent)
return orderEvent.EventType == nameof(OrderEventRejected);
public void Materialise(IOrderEvent orderEvent)
var orderEventReceived = orderEvent as OrderEventRejected;
Console.WriteLine("\n\t\tUpdating OrderPendingAggregation Status to Pending Aggregation");
Console.WriteLine($"\t\t{nameof(orderEventReceived.Id)}: {orderEventReceived.Id}");
Console.WriteLine($"\t\t{nameof(orderEventReceived.OrderReference)}: {orderEventReceived.OrderReference}");
Console.WriteLine($"\t\t{nameof(orderEventReceived.OrderPortfolioReference)}: {orderEventReceived.OrderPortfolioReference}");
public static void Main()
var factory = new OrderEventFactory();
var materialisers = new List<IOrderEventMaterialiser>
new OrderPendingAggregationMaterialiser(),
new OrderPendingAggregationCancellationMaterialiser(),
new OrderPendingAggregationRejectionMaterialiser()
var _changes = new List<OrderEvent>
new OrderEvent(nameof(OrderEventReceived), "ABC-131424", "ABCD-235235235235235235", 100m, 1),
new OrderEvent(nameof(OrderEventReceived), "ABC-131425", "ABCD-235235235235235237", 123m, 0),
new OrderEvent(nameof(OrderEventCancelled), "ABC-131424", "ABCD-235235235235235235"),
new OrderEvent(nameof(OrderEventRejected), "ABC-131425", "ABCD-235235235235235237")
Console.WriteLine($"\nReceived new change feed notification");
foreach(var change in _changes)
Console.WriteLine($"\n\tReceived new Item: {change.EventType}");
foreach(var materialiser in materialisers.Where(m => m.IsApplicable(change)))
IOrderEvent orderEvent = factory.GetOrderEvent(change);
materialiser.Materialise(orderEvent);