Skip to content

Instantly share code, notes, and snippets.

@RhysC
Last active December 31, 2015 19:59
Show Gist options
  • Save RhysC/8037101 to your computer and use it in GitHub Desktop.
Save RhysC/8037101 to your computer and use it in GitHub Desktop.
Scratch working of registering Mediator QueryHandlers with Autofac using the Query type interface, not their actual type for ShortBus mediator pattern (https://github.com/mhinze/ShortBus). Why? Because the Query implementations could/should be view models that are Web specific however the contract doesn't care about any of the crap that may be o…

Scratch working of registering Mediator QueryHandlers using the Query type interface, not their actual type. Why? Because the Query implementations could/should be view models that are Web specific however the contract doesn't care about any of the crap that may be on that type.

If we declare and implementation to have :

 IQueryHandler<IQuery<CustomerSummary[]>, CustomerSummary[]>,

then when we call

 public ActionResult Index(ClientListQuery query)  
        {  
            var customers = Mediator.Request(query);
            return View(customers.Data);
        }  

it wont resolve because

typeof(ClientListQuery) != typeof(IQuery<CustomerSummary[]>)

however ClientListQuery DOES implement implements IQuery<CustomerSummary[]>.

This gist solves that issue (note will need to repeat for commands)

private static void ConfigureContainer()
{
var containerBuilder = new ContainerBuilder();
var assembly = Assembly.GetExecutingAssembly();
containerBuilder.RegisterControllers(assembly);
containerBuilder.RegisterType<Mediator>().As<IMediator>();
containerBuilder.RegisterAssemblyTypes(typeof(CustomerService).Assembly)
.AsImplementedInterfaces();//Will regiter the
RegisterQueryHandlersByQueryInterfaces(containerBuilder);
containerBuilder.RegisterType<UnitOfWork>().AsImplementedInterfaces().InstancePerHttpRequest();
var container = containerBuilder.Build();
System.Web.Mvc.DependencyResolver.SetResolver(new AutofacDependencyResolver(container));
ShortBus.DependencyResolver.SetResolver(new ShortBus.Autofac.AutofacDependencyResolver(container));
}
private static void RegisterQueryHandlersByQueryInterfaces(ContainerBuilder containerBuilder)
{
var queryTypes = typeof (CustomerService)
.Assembly.GetTypes()
.Where(t => t.GetInterfaces().Any(i => i.IsGenericType && i.GetGenericTypeDefinition() == typeof (IQuery<>)))
.Distinct()
.ToArray();
var queryHandlerTypes = typeof (CustomerService)
.Assembly.GetTypes()
.Where(
t =>
t.GetInterfaces().Any(i => i.IsGenericType && i.GetGenericTypeDefinition() == typeof (IQueryHandler<,>)))
.ToArray();
foreach (var queryHandlerType in queryHandlerTypes)
{
foreach (var queryInterface in queryHandlerType.GetInterfaces().Where(i =>i.IsGenericType && i.GetGenericTypeDefinition() == typeof (IQueryHandler<,>)))
{
var @interface = queryInterface;
foreach(var queryType in queryTypes.Where(t => @interface.GenericTypeArguments.First().IsAssignableFrom(t)))
{
var responseType = queryType.GetInterfaces()
.Single(i => i.IsGenericType && i.GetGenericTypeDefinition() == typeof (IQuery<>))
.GetGenericArguments()
.First();
var genericType = typeof (IQueryHandler<,>).MakeGenericType(queryType, responseType);
containerBuilder.RegisterType(queryHandlerType)
.As(genericType);
}
}
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment