Skip to content

Instantly share code, notes, and snippets.

@KyorCode
Created January 16, 2013 20:23
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 KyorCode/4550550 to your computer and use it in GitHub Desktop.
Save KyorCode/4550550 to your computer and use it in GitHub Desktop.
public interface IWindsorContainer
{
// Windsor mock
KernelMock Kernel { get; set; }
object Resolve(Type commandHandlerType);
void Release(object commandHandler);
}
public class KernelMock
{
public bool HasComponent(Type commandHandlerType)
{
throw new NotImplementedException();
}
}
public class CommandHandlerNotFoundException : ApplicationException
{
public CommandHandlerNotFoundException(Type commandHandlerType)
{
// commandhandlernotfoundexception mock
}
}
public class QueryHandlerNotFoundException : ApplicationException
{
public QueryHandlerNotFoundException(Type queryHandlerType)
{
// queryhandlernotfoundexception mock
}
}
public interface IHandler
{
}
public interface ICommandHandler<in TCommand> : IHandler
{
void Handle(TCommand command);
}
public interface ICommandDispatcher
{
void Dispatch<TCommand>(TCommand command);
}
public class CommandDispatcher : ICommandDispatcher
{
private readonly IWindsorContainer _windsorContainer;
public CommandDispatcher(IWindsorContainer windsorContainer)
{
_windsorContainer = windsorContainer;
}
public void Dispatch<TCommand>(TCommand command)
{
var commandHandlerType = typeof(ICommandHandler<TCommand>);
var commandHandlerIsRegistered = _windsorContainer.Kernel.HasComponent(commandHandlerType);
if (!commandHandlerIsRegistered)
{
throw new CommandHandlerNotFoundException(commandHandlerType);
}
var commandHandler = (ICommandHandler<TCommand>)_windsorContainer.Resolve(commandHandlerType);
try
{
commandHandler.Handle(command);
}
finally
{
_windsorContainer.Release(commandHandler);
}
}
}
public interface IQueryDispatcher
{
TResult Dispatch<TRequest, TResult>(TRequest request);
}
public interface IQueryHandler<in TRequest, out TResult> : IHandler
{
TResult Handle(TRequest request);
}
public class QueryDispatcher : IQueryDispatcher
{
private readonly IWindsorContainer _windsorContainer;
public QueryDispatcher(IWindsorContainer windsorContainer)
{
_windsorContainer = windsorContainer;
}
public TResult Dispatch<TRequest, TResult>(TRequest request)
{
var queryHandlerType = typeof(IQueryHandler<TRequest, TResult>);
var queryHandlerIsRegistered = _windsorContainer.Kernel.HasComponent(queryHandlerType);
if (!queryHandlerIsRegistered)
{
throw new CommandHandlerNotFoundException(queryHandlerType);
}
var queryHandler = (IQueryHandler<TRequest, TResult>)_windsorContainer.Resolve(queryHandlerType);
try
{
var result = queryHandler.Handle(request);
return result;
}
finally
{
_windsorContainer.Release(queryHandler);
}
}
}
public interface IAccountService
{
void WithdrawAmount(WithdrawAmountCommand command);
TotalAmountResult GetTotalAmount(TotalAmountRequest request);
}
public class AccountService : IAccountService
{
private readonly IQueryDispatcher _queryDispatcher;
private readonly ICommandDispatcher _commandDispatcher;
public AccountService(IQueryDispatcher queryDispatcher, ICommandDispatcher commandDispatcher)
{
_queryDispatcher = queryDispatcher;
_commandDispatcher = commandDispatcher;
}
public void WithdrawAmount(WithdrawAmountCommand command)
{
_commandDispatcher.Dispatch(command);
}
public TotalAmountResult GetTotalAmount(TotalAmountRequest request)
{
return _queryDispatcher.Dispatch<TotalAmountRequest, TotalAmountResult>(request);
}
}
public class TotalAmountQueryHandler : IQueryHandler<TotalAmountRequest,TotalAmountResult>
{
private readonly IConstructorInjection _constructorInjection;
public TotalAmountQueryHandler(IConstructorInjection constructorInjection)
{
_constructorInjection = constructorInjection;
}
public TotalAmountResult Handle(TotalAmountRequest request)
{
var account = _constructorInjection.GetAcount(request.User);
return new TotalAmountResult{TotalAmount = account.Total};
// perform your command here with the data passed.
}
}
public class WithdrawAmountCommandHandler : ICommandHandler<WithdrawAmountCommand>
{
private readonly IConstructorInjection _constructorInjection;
public WithdrawAmountCommandHandler(IConstructorInjection constructorInjection)
{
_constructorInjection = constructorInjection;
}
public void Handle(WithdrawAmountCommand command)
{
var account = _constructorInjection.GetAcount(command.User);
account.Withdraw(command.Amount);
}
}
public interface IConstructorInjection
{
Account GetAcount(string user);
}
public class Account
{
private int _total;
public Account()
{
_total = 0;
}
public int Total
{
get { return _total; }
}
public void Withdraw(int amount)
{
_total -= amount;
}
}
#region Commands / Queries
public class WithdrawAmountCommand
{
public string User { get; set; }
public int Amount { get; set; }
}
public class TotalAmountRequest
{
public string User { get; set; }
}
public class TotalAmountResult
{
public int TotalAmount { get; set; }
}
#endregion
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment