Skip to content

Instantly share code, notes, and snippets.

View codescribler's full-sized avatar

Daniel Whittaker codescribler

View GitHub Profile
@codescribler
codescribler / AggregateRoot Simplified
Created November 13, 2014 22:08
A simplified aggregate root
public abstract class AggregateRoot
{
private readonly List<Event> _changes = new List<Event>();
public abstract Guid Id { get; }
public int Version { get; internal set; }
public IEnumerable<Event> GetUncommittedChanges()
{
// Removed for clarity
@codescribler
codescribler / CreateCustomer Controller
Last active August 29, 2015 14:08
MVC Event Sourcing Example with CRUD
[HttpPost]
public ActionResult CreateCustomer(Customer customer)
{
// Check business logic here (but no persistance)
if (DB.Customers.Values.ToList().Any(c => c.Name == customer.Name))
{
ModelState.AddModelError(string.Empty, "Duplicate Name Detected");
}
if (!ModelState.IsValid)
public class CustomerHandler
{
public void Handle(CustomerCreated customer)
{
// Do Insert
DB.Customers.Add(customer.Id, new Customer{Id = customer.Id, Name = customer.Name});
}
}
// ######################
@codescribler
codescribler / SimpleMessageRouter
Last active August 29, 2015 14:08
Example of a very simplistic internal message router
public class SimpleRouter
{
protected Dictionary<Type, List<Action<IEvent>>> Routes;
public SimpleRouter()
{
Routes = new Dictionary<Type, List<Action<IEvent>>>();
}
public void Register<T>(Action<T> handler) where T: IEvent
@codescribler
codescribler / Example Event
Created October 18, 2014 09:50
Structure of an Event message
public class CustomerCreated : Event
{
public readonly Guid AggreagteId;
public readonly int Version;
public readonly Guid UserId;
public readonly Guid ProcessId
// Other fields specific to this event
public CustomerCreated(Guid aggregateId, int version, Guid userId, Guid processId)
public class CustomerSummaryDenormaliser :
IHandle<CustomerCreated>,
IHandle<OrderPlaced>
{
private readonly CustomerSummaryDto _summaryDto;
public CustomerSummaryDenormaliser(CustomerSummaryDto summaryDto)
{
_summaryDto = summaryDto;
}
CustomerCreated(1, "Joe Blogs"));
OrderPlaced(1, 1, DateTime.Parse("2014-09-01"));
OrderPlaced(1, 2, DateTime.Parse("2014-09-02"));
OrderPlaced(1, 2, DateTime.Parse("2014-09-03"));
OrderPlaced(1, 2, DateTime.Parse("2014-09-04"));
OrderPlaced(1, 2, DateTime.Parse("2014-09-05"));
OrderPlaced(1, 2, DateTime.Parse("2014-09-06"));
OrderPlaced(1, 2, DateTime.Parse("2014-09-07"));
OrderPlaced(1, 2, DateTime.Parse("2014-09-08"));
public class CustomerCreated : Event
{
public readonly int Id;
public readonly string CustomerName;
public CustomerCreated(int id, string customerName)
{
Id = id;
CustomerName = customerName;
}
@codescribler
codescribler / Usage of conflict resolver
Created September 29, 2014 04:56
Example usage of conflict resolver
// UnApproved with conflict with Approved but nothing else
_concurrencyConflictResolver.RegisterConflictList(typeof(UnApproved), new List<Type> { typeof(Approved) });
// SignInRecorded doesnt conflict with anything
_concurrencyConflictResolver.RegisterConflictList(typeof(SignInRecorded), new List<Type>());
@codescribler
codescribler / Concurrency resolver
Created September 28, 2014 12:21
Example concurrency conflict resolution registry
public interface IConcurrencyConflictResolver
{
bool ConflictsWith(Type eventToCheck, IEnumerable<Type> previousEvents);
void RegisterConflictList(Type eventDefinition, List<Type> conflictsWith);
}
public class ConcurrencyConflictResolver : IConcurrencyConflictResolver
{
private readonly Dictionary<Type, List<Type>> _conflictRegister;