Friday, May 06, 2016

Getting started with MediatR and Unity

I've been able to put off figuring our how to properly manage the WebApi controllers in this new project because everything has been in "just make it work" mode, and I was not happy with any of the patterns I had used before. I've been reading about MediatR for a while now, and yesterday I had the chance to try and use it to manage the controller actions.

Short story, it worked almost right away. That was cool. However, MediatR requires a bit more "inside knowledge" type of configuration than do a lot of packages that I have used in the past. In this case, I had to figure out how to set up my Unity containers so that MediatR would be happy with them. Thankfully, there is code on the site that configures a Unity container, but it didn't work for me. This is the code currently in the MediatR samples (here):

    container.RegisterTypes(
        AllClasses.FromAssemblies(GetType().Assembly),
        WithMappings.FromAllInterfaces,
        GetName,
        GetLifetimeManager);

When I used this, I got an error at startup telling me that I was attempting to override and existing mapping to System.Web.Http.Controllers.IHttpController, moving it from one controller class in my project to another. Clearly, I had to tweak the registration. In the end, this is what I came up with:

    container.RegisterTypes(
        MediatRType()
        WithMappings.FromAllInterfaces,
        GetName,
        GetLifetimeManager);
and
    private IEnumerable MediatrTypes()
        {
            var _t = GetType().Assembly.DefinedTypes;
            var types = _t.Where(f => !f.IsInterface && f.GetInterfaces().Any(x => x.IsGenericType && (x.GetGenericTypeDefinition() == typeof(INotificationHandler<>) || x.GetGenericTypeDefinition() == typeof(IAsyncNotificationHandler<>) || x.GetGenericTypeDefinition() == typeof(IRequestHandler<,>) || x.GetGenericTypeDefinition() == typeof(IAsyncRequestHandler<,>) || x.GetGenericTypeDefinition() == typeof(IRequest<>))));
            return types;
        }

I'm thinking I should issue a pull request; I think this is a better mechanism.