Skip to content

Instantly share code, notes, and snippets.

@AlonAm
Last active August 8, 2016 11:45
Show Gist options
  • Save AlonAm/b76efecb436fbb1a67add18de1f85a69 to your computer and use it in GitHub Desktop.
Save AlonAm/b76efecb436fbb1a67add18de1f85a69 to your computer and use it in GitHub Desktop.
using Autofac;
using Autofac.Core;
using Cloudinator.Portal.WebApi.Infrastructure;
using Cloudinator.Portal.WebApi.Infrastructure.Handlers;
using FluentValidation;
using MediatR;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
namespace Cloudinator.Portal.WebApi.DependencyResolution
{
/// <summary>
/// In-process messaging.
/// Supports request/response, commands, queries, notifications and events, synchronous and async with intelligent dispatching via C# generic variance.
/// </summary>
public class MediatorModule : Autofac.Module
{
protected override void Load(ContainerBuilder builder)
{
builder.RegisterType<Mediator>()
.As<IMediator>()
.InstancePerLifetimeScope();
InstanceFactories(builder);
RequestPipeline(builder);
}
#region Helpers
private static void InstanceFactories(ContainerBuilder builder)
{
builder.Register<SingleInstanceFactory>(ctx =>
{
var c = ctx.Resolve<IComponentContext>();
return t => c.Resolve(t);
});
builder.Register<MultiInstanceFactory>(ctx =>
{
var c = ctx.Resolve<IComponentContext>();
return t => (IEnumerable<object>)c.Resolve(typeof(IEnumerable<>).MakeGenericType(t));
});
}
private static void RequestPipeline(ContainerBuilder builder)
{
Validation(builder);
Authorization(builder);
ErrorHandling(builder);
EventLogging(builder);
RequestHandling(builder);
}
private static void RequestHandling(ContainerBuilder builder)
{
builder.RegisterAssemblyTypes(Assembly.GetExecutingAssembly())
.As(type => type.GetInterfaces()
.Where(interfaceType => interfaceType.IsClosedTypeOf(typeof(IRequestHandler<,>)))
.Select(interfaceType => new KeyedService("handler", interfaceType)));
builder.RegisterAssemblyTypes(Assembly.GetExecutingAssembly())
.As(type => type.GetInterfaces()
.Where(interfaceType => interfaceType.IsClosedTypeOf(typeof(IAsyncRequestHandler<,>)))
.Select(interfaceType => new KeyedService("async-handler", interfaceType)));
}
private static void EventLogging(ContainerBuilder builder)
{
builder.RegisterGenericDecorator(typeof(AsyncLoggingHandler<,>), typeof(IAsyncRequestHandler<,>), fromKey: "async-handler", toKey: "async-logging-handler");
builder.RegisterGenericDecorator(typeof(LoggingHandler<,>), typeof(IRequestHandler<,>), fromKey: "handler", toKey: "logging-handler");
builder.RegisterAssemblyTypes(Assembly.GetExecutingAssembly())
.As(type => type.GetInterfaces()
.Where(interfacetype => interfacetype.IsClosedTypeOf(typeof(IEventLogger<,>))));
}
private static void Authorization(ContainerBuilder builder)
{
builder.RegisterGenericDecorator(typeof(AsyncAuthorizationHandler<,>), typeof(IAsyncRequestHandler<,>), fromKey: "async-logging-handler", toKey: "async-authorization-handler");
builder.RegisterGenericDecorator(typeof(AuthorizationHandler<,>), typeof(IRequestHandler<,>), fromKey: "logging-handler", toKey: "authorization-handler");
}
private static void ErrorHandling(ContainerBuilder builder)
{
builder.RegisterGenericDecorator(typeof(AsyncErrorHandler<,>), typeof(IAsyncRequestHandler<,>), fromKey: "async-authorization-handler", toKey: "async-error-handler");
builder.RegisterGenericDecorator(typeof(ErrorHandler<,>), typeof(IRequestHandler<,>), fromKey: "authorization-handler", toKey: "error-handler");
}
private static void Validation(ContainerBuilder builder)
{
builder.RegisterGenericDecorator(typeof(AsyncValidationHandler<,>), typeof(IAsyncRequestHandler<,>), fromKey: "async-error-handler");
builder.RegisterGenericDecorator(typeof(ValidationHandler<,>), typeof(IRequestHandler<,>), fromKey: "error-handler");
builder.RegisterAssemblyTypes(Assembly.GetExecutingAssembly())
.As(type => type.GetInterfaces()
.Where(interfacetype => interfacetype.IsClosedTypeOf(typeof(IValidator<>))));
}
#endregion
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment