Mediator pattern
I have been criticized for implementing the mediator pattern in many companies. Everyone rightly want to use MediaR. I wrote the mediator pattern many years ago using reflection, after C# added functional programming I changed to the implementation below. I also have implemented using Java 8 chaining functions following a filter pipe to route request based on Type.
I was looking to leverage minimal external libraries as oppositive to use open source libraries as building block that leads me to this implementation.
Mediator pattern is commonly used to decouple components, whether is direct calls or message driven. I wrote a simple function that decouple components and leverage Dot Net Core service collection to route request.
Usage:
[HttpPost]
[ProducesResponseType(typeof(AddYardView), 200)]
[ProducesResponseType(typeof(ValidationStatus), 400)]
[ProducesResponseType(typeof(NotFound), 404)]
public async Task<IActionResult> Post([FromBody] AddYard addYard, CancellationToken token)
{
return await _reqRouter.Route<AddYard, AddYardView>(addYard, token)
.ConfigureAwait(false);
}
Implementation:
public interface IReqRouter
{
Task<ReqResult<TResult>> Route<TReq, TResult>(TReq command, CancellationToken token = default)
where TReq : IReq;
}
public class ReqRouter : IReqRouter
{
private readonly IServiceProvider _serviceProvider;
private readonly ILogger<ReqRouter> _logger;
public ReqRouter(IServiceProvider serviceProvider,
ILogger<ReqRouter> logger)
{
_serviceProvider = serviceProvider;
_logger = logger;
}
public async Task<ReqResult<TResult>> Route<TReq, TResult>(TReq command, CancellationToken token = default) where TReq : IReq
{
try
{
var handler = _serviceProvider.GetRequiredService<IReqService<TReq, TResult>>();
if (handler == null)
{
return ReqResult<TResult>.ServerError(new ServerError { Message = "Handler not found" });
}
return await handler.Handle(command, token).ConfigureAwait(false);
}
catch (Exception ex)
{
_logger.LogError(ex, ex.Message);
return ReqResult<TResult>.ServerError(new ServerError { Message = ex.Message });
}
}
}