Skip to content

Instantly share code, notes, and snippets.

@NinoFloris
Created December 9, 2016 18:16
Show Gist options
  • Save NinoFloris/af0156dadfebe6b5d36026964d9a0f40 to your computer and use it in GitHub Desktop.
Save NinoFloris/af0156dadfebe6b5d36026964d9a0f40 to your computer and use it in GitHub Desktop.
Mediator pipeline proof of concept
public delegate Task<TResponse> RequestHandlerDelegate<TResponse>(IAsyncRequest<TResponse> request);
public interface IRequestHandler<TRequest, TResponse> where TRequest : IAsyncRequest<TResponse>
{
Task<TResponse> Handle(TRequest message, RequestHandlerDelegate<TRequest, TResponse> next);
}
public class MediatorDecorator : IMediator
{
// [...]
public async Task<TResponse> SendAsync<TResponse>(IAsyncRequest<TResponse> request)
{
var closedType = typeof(IRequestHandler<,>).MakeGenericType(request.GetType(), typeof(TResponse));
var decorators = _container.GetAllInstances(closedType);
var pipelineSteps = new List<Func<RequestHandlerDelegate<TResponse>, RequestHandlerDelegate<TResponse>>>();
foreach (var decorator in decorators)
{
var method = decorator.GetType().GetMethod("Handle", new[] { request.GetType(), typeof(RequestHandlerDelegate<TResponse>) });
var step = new Func<RequestHandlerDelegate<TResponse>, RequestHandlerDelegate<TResponse>>(
next => async r => await (Task<TResponse>)method.Invoke(decorator, new object[] { r, next }));
pipelineSteps.Add(step);
}
var finalFunc = new Func<RequestHandlerDelegate<TResponse>, RequestHandlerDelegate<TResponse>>(
ignoreNext => async r => await _innerMediator.SendAsync<TResponse>(r));
pipelineSteps.Add(finalFunc);
pipelineSteps.Reverse();
RequestHandlerDelegate<TResponse> pipeline = null;
foreach (var step in pipelineSteps)
{
pipeline = step.Invoke(pipeline);
}
return await pipeline.Invoke(request);
}
// [...]
}
// Registration
For(typeof(IRequestHandler<,>)).Add(typeof(RequestHandlerWithTx<,>));
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment