Skip to content

Instantly share code, notes, and snippets.

@randomcodenz
Created February 10, 2014 21:29
Show Gist options
  • Save randomcodenz/8924561 to your computer and use it in GitHub Desktop.
Save randomcodenz/8924561 to your computer and use it in GitHub Desktop.
Lightweight CQS / DomainEvents Infrastructure
namespace Domain.Commands
{
public interface ICommandInvoker
{
// Extreme CQS - probably should have a version of execute that can return an Id<T>
void Execute<T>( T command );
}
// If you alter the void Execute<T> in ICommandInvoker you will need to alter this as well
public interface ICommandHandler<T>
{
void Handle( T command );
}
public class CommandInvoker : ICommandInvoker
{
private readonly IContainer _container;
public CommandInvoker( IContainer container )
{
_container = container;
}
public void Execute<T>( T command )
{
var handler = _container.TryGetInstance<ICommandHandler<T>>();
if( handler == null )
{
throw new CommandHandlerNotFoundException<T>();
}
handler.Handle( command );
}
}
public class CommandHandlerNotFoundException<T> : ApplicationException
{
public override string Message
{
get
{
return "A command handler implementing ICommandHandler<{0}> was not found in the container. " +
"Please check the command handler exists and has been registered in the container."
.FormatWith( typeof( T ).Name );
}
}
}
}
namespace Domain.Events
{
public interface IDomainEvent {}
public interface IDomainEventsHandler
{
void Raise<T>( T args ) where T : IDomainEvent;
}
public interface IEventHandlerResolver
{
IEnumerable<IHandles<T>> ResolveAll<T>() where T : IDomainEvent;
}
public interface IHandles<T> where T : IDomainEvent
{
void Handle( T args );
}
public static class DomainEvents
{
private static IDomainEventsHandler _handler;
public static bool IsInitialised()
{
return _handler != null;
}
public static void Initialise( IDomainEventsHandler handler )
{
_handler = handler;
}
public static void Raise<T>( T args ) where T : IDomainEvent
{
EnsureInitialised();
_handler.Raise( args );
}
public static void ResetHandler()
{
_handler = null;
}
private static void EnsureInitialised()
{
if( _handler == null )
{
throw new InvalidOperationException( "DomainEvents has not been initialised. Initialise( IDomainEventsHandler ) must be called prior to raising events." );
}
}
}
public class DefaultDomainEventsHandler : IDomainEventsHandler
{
private readonly IEventHandlerResolver _handlerResolver;
public DefaultDomainEventsHandler( IEventHandlerResolver handlerResolver )
{
_handlerResolver = handlerResolver;
}
public void Raise<T>( T args ) where T : IDomainEvent
{
var eventHandlers = _handlerResolver.ResolveAll<T>();
foreach( var handler in eventHandlers )
{
handler.Handle( args );
}
}
}
}
namespace Web.Views
{
public interface IViewRepository
{
TView Load<TView>();
TView Load<TInput, TView>( TInput input );
}
public interface IViewFactory<TView>
{
TView Load();
}
public interface IViewFactory<TInput,TView>
{
TView Load( TInput input );
}
public class ViewRepository : IViewRepository
{
private readonly IContainer _container;
public ViewRepository( IContainer container )
{
_container = container;
}
public TView Load<TView>()
{
var factory = _container.TryGetInstance<IViewFactory<TView>>();
if( factory == null )
{
throw new ViewFactoryNotFoundException<TView>();
}
return factory.Load();
}
public TView Load<TInput,TView>( TInput input )
{
var factory = _container.TryGetInstance<IViewFactory<TInput, TView>>();
if( factory == null )
{
throw new ViewFactoryNotFoundException<TInput,TView>();
}
return factory.Load( input );
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment