Created
October 11, 2011 07:48
-
-
Save chaliy/1277512 to your computer and use it in GitHub Desktop.
Reduce function for events
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.Linq; | |
using System.Text; | |
using OrderId = System.String; | |
using Address = System.String; | |
using System.Reactive.Subjects; | |
class Program | |
{ | |
static void Main(string[] args) | |
{ | |
// Two initial events | |
var events = new List<dynamic> | |
{ | |
new OrderCheckedOut | |
{ | |
OrderId = "Foo1", | |
EstimatedTotal = 12.0m, | |
OrderNumber = "Foo1", | |
History = new List<string>{"Order Foo1 checked out" } | |
}, | |
new OrderPaid | |
{ | |
OrderId = "Foo1", | |
PaidTotal = 12.0m, | |
History = new List<string>{"Order Foo1 paid with 12.0$" } | |
} | |
}; | |
// Reduce to result document | |
var docs = Reduce(events); | |
var foo1Doc = docs.First(); | |
Console.WriteLine(foo1Doc); | |
// Next events + document from last reduce | |
var nextEvents = new List<dynamic> | |
{ | |
foo1Doc, | |
new OrderDispatched | |
{ | |
OrderId = "Foo1", | |
History = new List<string>{"Order Foo1 dispatched" } | |
} | |
}; | |
var docs2 = Reduce(nextEvents); | |
var foo1Doc2 = docs2.First(); | |
Console.WriteLine(foo1Doc2); | |
// Result is reduce of all three events. | |
} | |
public static IEnumerable<OrderDocument> Reduce(IEnumerable<dynamic> input) | |
{ | |
return from e in input | |
group e by e.OrderId into g | |
select new OrderDocument | |
{ | |
OrderId = g.Key, | |
OrderNumber = Last(g, gg => gg.OrderNumber), | |
OrderDate = Last(g, gg => gg.OrderDate), | |
EstimatedTotal = Last(g, gg => gg.EstimatedTotal), | |
PaidTotal = Last(g, gg => gg.PaidTotal), | |
History = g.SelectMany<dynamic, string>(gg => gg.History).ToList() | |
}; | |
} | |
private static dynamic Last(IEnumerable<dynamic> input, Func<dynamic, dynamic> selector) | |
{ | |
foreach (var item in input.Reverse()) | |
{ | |
try | |
{ | |
return selector(item); | |
} | |
catch{} | |
} | |
return default(dynamic); | |
} | |
} | |
// Events | |
public class OrderCheckedOut | |
{ | |
public OrderId OrderId { get; set; } | |
public string OrderNumber { get; set; } | |
public DateTime OrderDate { get; set; } | |
public decimal EstimatedTotal { get; set; } | |
public IList<string> History { get; set; } | |
} | |
public class OrderAddressChanged | |
{ | |
public OrderId OrderId { get; set; } | |
public Address Address { get; set; } | |
public IList<string> History { get; set; } | |
} | |
public class OrderPaid | |
{ | |
public OrderId OrderId { get; set; } | |
public DateTime PaymentDate { get; set; } | |
public decimal PaidTotal { get; set; } | |
public IList<string> History { get; set; } | |
} | |
public class OrderDispatched | |
{ | |
public OrderId OrderId { get; set; } | |
public string Comments { get; set; } | |
public IList<string> History { get; set; } | |
} | |
// Domain | |
public class OrderDocument | |
{ | |
public OrderId OrderId { get; set; } | |
public string OrderNumber { get; set; } | |
public DateTime OrderDate { get; set; } | |
public decimal EstimatedTotal { get; set; } | |
public Address Address { get; set; } | |
public DateTime PaymentDate { get; set; } | |
public decimal PaidTotal { get; set; } | |
public bool IsDispatched { get; set;} | |
public string DispatchComments { get; set; } | |
public IList<string> History { get ; set; } | |
public OrderDocument () | |
{ | |
History = new List<string>(); | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment