Skip to content

Instantly share code, notes, and snippets.

@rippo
Last active November 14, 2024 15:46
Show Gist options
  • Save rippo/7838d835d279758cd221f431f5dbf2f2 to your computer and use it in GitHub Desktop.
Save rippo/7838d835d279758cd221f431f5dbf2f2 to your computer and use it in GitHub Desktop.
Mediator Pattern using simple Injector
public interface IMediator
{
TResponse Request<TResponse>(IQuery<TResponse> query);
Task<TResponse> RequestAsync<TResponse>(IQuery<TResponse> query);
void Send(ICommand command);
Task SendAsync(ICommand command);
void Validate(IValidation validation);
Task ValidateAsync(IValidation validation);
}
[ExcludeFromCodeCoverage]
public sealed class Mediator : IMediator
{
[DebuggerStepThrough]
public TResponse Request<TResponse>(IQuery<TResponse> query)
{
var handlerType = typeof(IQueryHandler<,>).MakeGenericType(query.GetType(), typeof(TResponse));
dynamic handler = container.GetInstance(handlerType);
return handler.Handle((dynamic)query);
}
[DebuggerStepThrough]
public async Task<TResponse> RequestAsync<TResponse>(IQuery<TResponse> query)
{
var handlerType = typeof(IQueryAsyncHandler<,>).MakeGenericType(query.GetType(), typeof(TResponse));
dynamic handler = container.GetInstance(handlerType);
return await handler.HandleAsync((dynamic)query);
}
[DebuggerStepThrough]
public void Send(ICommand command)
{
var handlerType = typeof(ICommandHandler<>).MakeGenericType(command.GetType());
dynamic handler = container.GetInstance(handlerType);
handler.Execute((dynamic)command);
}
[DebuggerStepThrough]
public async Task SendAsync(ICommand command)
{
var handlerType = typeof(ICommandAsyncHandler<>).MakeGenericType(command.GetType());
dynamic handler = container.GetInstance(handlerType);
await handler.ExecuteAsync((dynamic)command);
}
[DebuggerStepThrough]
public void Validate(IValidation validation)
{
var handlerType = typeof(IValidationHandler<>).MakeGenericType(validation.GetType());
dynamic handler = container.GetInstance(handlerType);
handler.Validate((dynamic)validation);
}
[DebuggerStepThrough]
public async Task ValidateAsync(IValidation validation)
{
var handlerType = typeof(IValidationAsyncHandler<>).MakeGenericType(validation.GetType());
dynamic handler = container.GetInstance(handlerType);
await handler.ValidateAsync((dynamic)validation);
}
private readonly Container container;
public Mediator(Container container)
{
this.container = container;
}
}
public class GetAllDunBradstreetHandler : IQueryAsyncHandler<GetAllDunBradstreetQuery, GetAllDunBradstreetViewModel>
{
public async Task<GetAllDunBradstreetViewModel> HandleAsync(GetAllDunBradstreetQuery query)
{
using var connection = ConnectionFactory.GetOpenConnection();
return new GetAllDunBradstreetViewModel
{
Data = await connection.QueryAsync<DunAndBradstreetRecordDto>(
"select * from dunbradstreet order by CompanyName, Duns;")
};
}
}
public class GetAllDunBradstreetQuery : IQuery<GetAllDunBradstreetViewModel>
{
}
public class GetAllDunBradstreetViewModel
{
public IEnumerable<DunAndBradstreetRecordDto> Data { get; set; }
}
...
private void InitializeContainer()
{
container.Register(typeof(ICommandHandler<>), typeof(ICommandHandler<>).Assembly);
container.Register(typeof(ICommandAsyncHandler<>), typeof(ICommandAsyncHandler<>).Assembly);
container.Register(typeof(IQueryHandler<,>), typeof(IQueryHandler<,>).Assembly);
container.Register(typeof(IQueryAsyncHandler<,>), typeof(IQueryAsyncHandler<,>).Assembly);
container.Register(typeof(IValidationHandler<>), typeof(IValidationHandler<>).Assembly);
container.Register(typeof(IValidationAsyncHandler<>), typeof(IValidationAsyncHandler<>).Assembly);
container.Register<IMediator, Mediator>(Lifestyle.Scoped);
...
@rippo
Copy link
Author

rippo commented Nov 14, 2024

Usage from any end point

ViewModel = await mediator.RequestAsync(new GetAllDunBradstreetQuery());

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment