Created
January 16, 2013 20:23
-
-
Save KyorCode/4550550 to your computer and use it in GitHub Desktop.
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
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