Skip to content

Instantly share code, notes, and snippets.

@pradeepn
Created January 3, 2017 10:51
Show Gist options
  • Save pradeepn/639bfe6f690956998a0140ecb33027e9 to your computer and use it in GitHub Desktop.
Save pradeepn/639bfe6f690956998a0140ecb33027e9 to your computer and use it in GitHub Desktop.
MediatR MediatorPipeline
public class MediatRInstaller : IWindsorInstaller
{
public void Install(IWindsorContainer container, IConfigurationStore store) {
container.Register(Classes.FromAssemblyContaining<IMediator>().Pick().WithServiceAllInterfaces());
container.Kernel.AddHandlersFilter(new ContravariantFilter());
container.Register(Classes.FromThisAssembly().BasedOn(typeof (IRequestHandler<,>)).WithService.AllInterfaces().LifestyleTransient());
container.Register(Classes.FromThisAssembly().BasedOn(typeof (IPreRequestHandler<>)).WithService.AllInterfaces().LifestyleTransient());
container.Register(Classes.FromThisAssembly().BasedOn(typeof (IPostRequestHandler<,>)).WithService.AllInterfaces().LifestyleTransient());
container.Register(Classes.FromThisAssembly().BasedOn(typeof (INotificationHandler<>)).WithService.AllInterfaces().LifestyleTransient());
// http://stackoverflow.com/questions/4240593/castle-windsor-registration-of-open-generic-decorator-types
(from t in this.GetType().Assembly.GetTypes()
let i = t.GetInterfaces().SingleOrDefault(i => i.IsGenericType && i.GetGenericTypeDefinition() == typeof (IRequestHandler<,>))
where t.IsClass && !t.IsAbstract && i != null && !typeof (MediatorPipeline<,>).IsAssignableFrom(t)
select i).ForEach(h => container.Register(Component
.For(h)
.ImplementedBy((typeof (MediatorPipeline<,>)).MakeGenericType(h.GetGenericArguments()))
.IsDefault()
.LifestyleTransient()
));
container.Kernel.Resolver.AddSubResolver(new ArrayResolver(container.Kernel, true));
var serviceLocator = new WindsorServiceLocator(container);
var serviceLocatorProvider = new ServiceLocatorProvider(() => serviceLocator);
container.Register(Component.For<ServiceLocatorProvider>().Instance(serviceLocatorProvider));
}
}
public interface IPreRequestHandler<in TRequest>
{
void Handle(TRequest request);
}
public interface IPostRequestHandler<in TRequest, in TResponse>
{
void Handle(TRequest request, TResponse response);
}
public class MediatorPipeline<TRequest, TResponse>
: IRequestHandler<TRequest, TResponse>
where TRequest : IRequest<TResponse>
{
private readonly IRequestHandler<TRequest, TResponse> _inner;
private readonly IPreRequestHandler<TRequest>[] _preRequestHandlers;
private readonly IPostRequestHandler<TRequest, TResponse>[] _postRequestHandlers;
public MediatorPipeline(
IRequestHandler<TRequest, TResponse> inner,
IPreRequestHandler<TRequest>[] preRequestHandlers,
IPostRequestHandler<TRequest, TResponse>[] postRequestHandlers
) {
_inner = inner;
_preRequestHandlers = preRequestHandlers;
_postRequestHandlers = postRequestHandlers;
}
public TResponse Handle(TRequest message) {
foreach (var preRequestHandler in _preRequestHandlers) {
preRequestHandler.Handle(message);
}
var result = _inner.Handle(message);
foreach (var postRequestHandler in _postRequestHandlers) {
postRequestHandler.Handle(message, result);
}
return result;
}
}
public class ContravariantFilter : IHandlersFilter
{
public bool HasOpinionAbout(Type service) {
if (!service.IsGenericType) {
return false;
}
var genericType = service.GetGenericTypeDefinition();
var genericArguments = genericType.GetGenericArguments();
return genericArguments.Count() == 1
&& genericArguments.Single().GenericParameterAttributes.HasFlag(GenericParameterAttributes.Contravariant);
}
public IHandler[] SelectHandlers(Type service, IHandler[] handlers) {
return handlers;
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment