Created
February 10, 2014 21:29
-
-
Save randomcodenz/8924561 to your computer and use it in GitHub Desktop.
Lightweight CQS / DomainEvents Infrastructure
This file contains 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
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 ); | |
} | |
} | |
} | |
} |
This file contains 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
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 ); | |
} | |
} | |
} | |
} |
This file contains 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
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