Skip to content

Instantly share code, notes, and snippets.

@joliver
Created November 2, 2009 20:04
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save joliver/224412 to your computer and use it in GitHub Desktop.
Save joliver/224412 to your computer and use it in GitHub Desktop.
CQRS Sample Routing Table
private static void Main()
{
IContainer container = null; // build container here
RegisterRoutes(container); // routes don't change
using (threadSpecificContainer = container.CreateInnerContainer())
{
var handler = new UnitOfWorkMessageHandler<IContainer>(
threadSpecificContainer,
new TransactionScope(),
new UnitOfWork(),
threadSpecificContainer.Resolve<RoutingTable<IContainer>>());
using (handler)
handler.Handle(commandMessage);
}
}
public class RoutingTable<TContainer>
{
private readonly IDictionary<Type, ICollection<Action<TContainer, IMessage>>> table =
new Dictionary<Type, ICollection<Action<TContainer, IMessage>>>();
public void Register<TMessage>(Action<TContainer, TMessage> route) where TMessage : class, IMessage
{
ICollection<Action<TContainer, IMessage>> routes;
var routingKey = typeof(TMessage);
if (!this.table.TryGetValue(routingKey, out routes))
this.table[routingKey] = routes = new LinkedList<Action<TContainer, IMessage>>();
routes.Add((container, message) => route(container, message as TMessage));
}
public void Route(TContainer container, IMessage message)
{
ICollection<Action<TContainer, IMessage>> routes;
if (!this.table.TryGetValue(message.GetType(), out routes))
throw new RouteNotRegisteredException(message.GetType());
foreach (var route in routes)
route(container, message);
}
}
public class UnitOfWorkMessageHandler<TContainer> : IHandleMessages
where TContainer : IDisposable
{
private readonly TContainer container;
private readonly TransactionScope transaction;
private readonly IUnitOfWork unitOfWork;
private readonly RoutingTable<TContainer> routes;
public UnitOfWorkMessageHandler(
TContainer container, TransactionScope transaction, IUnitOfWork unitOfWork, RoutingTable<TContainer> routes)
{
this.container = container;
this.transaction = transaction;
this.unitOfWork = unitOfWork;
this.routes = routes;
}
public void Handle(params IMessage[] messages)
{
this.Handle(messages.AsEnumerable());
}
public void Handle(IEnumerable<IMessage> messages)
{
foreach (var message in messages)
this.routes.Route(this.container, message);
this.unitOfWork.Complete();
this.transaction.Complete();
}
public void Dispose()
{
this.unitOfWork.Dispose();
this.transaction.Dispose();
this.container.Dispose();
GC.SuppressFinalize(this);
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment