Skip to content

Instantly share code, notes, and snippets.

@joliver
Created November 3, 2009 17:40
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save joliver/225264 to your computer and use it in GitHub Desktop.
Save joliver/225264 to your computer and use it in GitHub Desktop.
namespace Cqrs.Domain
{
using System;
using Messages;
public abstract class BaseAggregateRoot<TAggregate> : IAggregateRoot
where TAggregate : class, IAggregateRoot
{
private static readonly IDispatchMessages<TAggregate> Dispatcher = new MessageDispatcher<TAggregate>();
protected static void Register<TMessage>(Action<TAggregate, TMessage> handler) where TMessage : class, IMessage
{
Dispatcher.Register(handler);
}
protected void Apply(IEvent message)
{
(this as IApplyEvents).Apply(message);
}
void IApplyEvents.Apply(IEvent message)
{
message.AggregateVersion = ++this.AggregateVersion;
Dispatcher.Dispatch(this as TAggregate, message);
this.uncommitted.Add(message);
}
}
}
namespace Cqrs.Domain
{
using System;
using System.Collections.Generic;
using Messages;
public class MessageDispatcher<TTarget> : IDispatchMessages<TTarget>
{
private readonly IDictionary<Type, ICollection<Action<TTarget, IMessage>>> registrations =
new Dictionary<Type, ICollection<Action<TTarget, IMessage>>>();
public void Register<TMessage>(Action<TTarget, TMessage> route) where TMessage : class, IMessage
{
var routes = this.GetOrCreateRoutesFor<TMessage>(typeof(TMessage));
routes.Add((target, message) => route(target, message as TMessage));
}
private ICollection<Action<TTarget, IMessage>> GetOrCreateRoutesFor<TMessage>(Type key)
{
var routes = this.GetRoutesFor(key);
if (routes == null)
this.registrations[typeof(TMessage)] = routes = new LinkedList<Action<TTarget, IMessage>>();
return routes;
}
private ICollection<Action<TTarget, IMessage>> GetRoutesFor(Type key)
{
ICollection<Action<TTarget, IMessage>> routes;
this.registrations.TryGetValue(key, out routes);
return routes;
}
public void Dispatch(TTarget target, IMessage message)
{
foreach (var route in this.GetRoutesOrThrowFor(message.GetType()))
route(target, message);
}
private ICollection<Action<TTarget, IMessage>> GetRoutesOrThrowFor(Type key)
{
var routes = this.GetRoutesFor(key);
if (null == routes)
throw new MessageNotRegisteredException(key);
return routes;
}
}
}
namespace Cqrs.SimpleTestDomain.Aggregates
{
using System;
using Domain;
using Events;
public class User : BaseAggregateRoot<User>
{
static User()
{
Register<UserCreatedEvent>((user, msg) => user.OnCreated(msg));
Register<UserAuthenticatedEvent>((agg, msg) => agg.OnAuthenticated(msg));
}
public void Authenticate()
{
var msg = new UserAuthenticatedEvent(this.AggregateId, DateTime.UtcNow);
this.Apply(msg);
}
private void OnCreated(UserCreatedEvent msg)
{
this.created = msg.Created;
}
private void OnAuthenticated(UserAuthenticatedEvent msg)
{
this.authenticated = msg.Authenticated;
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment