Advanced StructureMap: connecting implementations to open generic types

One pattern we’re starting to see more and more is the idea of connecting messages to handlers.  These messages might be domain command messages, ActionResult messages, and more.  Beyond messaging implementations, we start to see a more basic pattern start to emerge.  We have some interface describing a contract that happens to be generic:

public interface IFooService<T>
{
    void DoSomething(int value, T foo);
}

Now, if we weren’t doing IoC, and we needed a specific FooService for some type T, we’d have to know which type to get.  But you might start to see situations where you need an IFooService<T>, but you don’t really care about the T specifically:

public class SomethingThatUsesFoo<T>
{
    private readonly IFooService<T> _service;

    public SomethingThatUsesFoo(IFooService<T> service)
    {
        _service = service;
    }

    public void SomethingSpecific(T value)
    {
        _service.DoSomething(4, value);
    }
}

As you start to build more and more generic components, building out common infrastructure components, you’ll start to build more common services like these, that coordinate between a messages and their handlers.  In most cases like these, we’re not using generics for type safety, but rather for metadata to match up input types to output services.  A more concrete example on a real project looks like this:

public interface IHandler<TEvent> 
{
    void Handle(TEvent args);
}

This is an interface for domain events, where we’ll have handlers like:

public class OrderCanceledEvent
    : IHandler<OrderCanceledMessage>
{
    public void Handle(OrderCanceledMessage args)
    {
        // send an email or something
    }
}

Now the trick is, how do we instruct our Inversion of Control container to locate the right handler for the right event?  If you’re using StructureMap, it’s dirt, dirt simple.

Configuring StructureMap

Because we’re using StructureMap, we’ll be using a custom Registry to do our configuration.  To connect implementations, we want to make sure that any time we ask StructureMap for an IHandler<T>, it finds the concrete type of handler T.  In the above example, our common message routing code will ask for an IHandler<OrderCanceledMessage>, and the type located needs to be OrderCanceledEvent, because OrderCanceledEvent implements the IHandler<OrderCanceledMessage>.

Our Registry winds up being very simple:

public class HandlerRegistry : Registry
{
    public HandlerRegistry()
    {
        Scan(cfg =>
        {
            cfg.TheCallingAssembly();
            cfg.IncludeNamespaceContainingType<OrderCanceledEvent>();
            cfg.ConnectImplementationsToTypesClosing(typeof(IHandler<>));
        });
    }
}

To connect implementations to our open generic type of IHandler<T>, we use the ConnectImplementationsToTypesClosing method.  The other two are just directions telling StructureMap where to look for my handlers.  Typically, my registration code lives in the same assembly as the actual interfaces I’m registering, but you can also register by name.

But that’s it!  Very simple, one line to connect all of the handlers to their implementations.  I can verify this with a simple test:

[Test]
public void Should_connect_types()
{
    ObjectFactory.Initialize(init =>
    {
        init.AddRegistry<HandlerRegistry>();
    });

    ObjectFactory.AssertConfigurationIsValid();

    Debug.WriteLine(ObjectFactory.WhatDoIHave());

    var handler = ObjectFactory.GetInstance<IHandler<OrderCanceledMessage>>();

    handler.ShouldBeInstanceOf<OrderCanceledEvent>();
}

This test passes, and all is well in IoC land.

Embracing the container

At some point, users of IoC learn to stop caring and love the bomb container.  In our system, we have no less than ten usages of this method, meaning we have refactored a lot of common plumbing and coordinators into our infrastructure layer.  We can easily add new handlers, mappers, repositories, providers, commands, builders, invokers, etc., all with one line of configuration for each open type (NOT one per derived type/implementation).  It certainly opens the doors to new possibilities of separation of concerns between different pieces, we just happen to lean on the type system to route our information around.

Something to note here is that at no time did I need to describe the implementors.  StructureMap’s scanner merely found implementations of types closing IHandler<T>, and connected that concrete type to the requested type of IHandler<SpecificType>.  I’ve taken a look at the other containers, and frankly, I haven’t found any that match this level of simplicity in configuration.  But I’m not an expert on the other containers, so I’d love to be proven wrong!

Regardless, I absolutely love this pattern of usage in IoC.  It promotes a level of SOLID design that’s pretty tough to beat.  When folks talk about IoC only being useful in large or complex projects, I just don’t understand it.  Usages like this give me Separation of Concerns from the get-go, at almost zero cost.  If only other frameworks were built with this in mind

Related Articles:

Post Footer automatically generated by Add Post Footer Plugin for wordpress.

About Jimmy Bogard

I'm a technical architect with Headspring in Austin, TX. I focus on DDD, distributed systems, and any other acronym-centric design/architecture/methodology. I created AutoMapper and am a co-author of the ASP.NET MVC in Action books.
This entry was posted in StructureMap. Bookmark the permalink. Follow any comments here with the RSS feed for this post.
  • http://erichauser.net/ Eric Hauser

    Windsor can handle this scenario as well. James Kovacs has a write up:

    http://www.devx.com/codemag/Article/41963/1763/page/5

  • http://blogs.dovetailsoftware.com/blogs/kmiller/ Kevin Miller

    Great post Jimmy.

    I am using the same technique to wire up message consumers (handlers) to be MassTransit message bus subscribers.

    I love how simple it is to let the StructureMap scanner do the hard stuff.

  • http://jeffbarnes.net/blog Jeff Barnes

    Thanks for the tip.

    I’m using a similar handler concept for a CQRS implementation with a WCF command service and query service that dispatch messages to handlers. I’m also using StructureMap and had overlooked this feature. This will be a *big* time saver.

  • http://www.lostechies.com/members/bogardj/default.aspx bogardj

    @Eric Hauser

    That’s not quite the same solution. In that post, you’re connecting an open generic interface to an open generic implementation. In my example, you’re connecting types that close the generic interface to its implementation.

    For example, we have around 200 implementors of a Command. Registering all 200 unique implementors requires 1 line of StructureMap registration code.

  • http://joshuaflanagan.lostechies.com Joshua Flanagan

    @Eric – that Windsor example is a little different from what Jimmy is talking about. In James example, he is explicitly telling the Windsor which concrete (Repository) type to use for the interface (IRepository).
    In the StructureMap example, Jimmy never explicitly tells the container which concrete type to use. This allows concrete types with different implementations such as OrderRepository and CustomerRepository, instead of just Repository and Repository (which really have the same implementation).

  • http://www.LinkedTraining.com.au Paul Linton

    What version of SM has ConnectImplementationsToTypesClosing? Has it been released?
    thanks

  • http://erichauser.net/ Eric Hauser

    @Jimmy/Joshua

    Correct, James article does not show how to register this scenario. Here’s an example using the registration API:

    kernel.Register(AllTypes.Pick().FromAssembly(Assembly.GetExecutingAssembly()).BasedOn(typeof(ICommand<>)).WithService.Base());

  • http://www.lostechies.com/members/bogardj/default.aspx bogardj

    @Paul

    This is in the trunk version, but will be in the upcoming 2.5.4 release.

    @Eric

    What does WithService.Base() do exactly?

  • http://autoregistration.codeplex.com/ Artem Govorov

    >I’ve taken a look at the other containers, and frankly, I haven’t
    >found any that match this level of simplicity in configuration. But
    >I’m not an expert on the other containers, so I’d love to be
    >proven wrong!
    I think you’ve described special case usage of more general auto registration feature. I have implemented general auto registration solution with nice fluent syntax for Unity (see here http://autoregistration.codeplex.com/), Marcin Budny had created predicate for open generics to simplify registering them (http://marcinbudny.blogspot.com/2009/11/unity-auto-registration.html). You can have a look and compare readability and simplicity.

  • http://ctrl-shift-b.com Derek Greer

    Very cool stuff. I added this ability to an extension I wrote for Unity (see http://bit.ly/6FcCwl) after you first tweeted about it back in August, but its features like this that have made me consider StructureMap for future projects.

  • http://blog.mikeobrien.net mob

    This is pretty sweet. I just knocked down all my individual repository registrations to a few lines. Thanks for pointing this out.

  • http://blog.viabrains.com Martin Nilsson

    In Windsor:

    //Registration
    Kernel.Register(AllTypes.Of(typeof(IHandler<>)).FromAssembly(typeof(OrderCanceledEvent).Assembly).WithService.FirstInterface());

    //Implementation
    public class OrderCanceledEvent : IHandler
    {}

    //Usage
    public class SomeClass(IHandler handler)
    {}

  • http://blog.coreycoreycoogan.com corey coogan

    Great article Jimmy. One thing that I’m missing here is how you go about raising the events or calling the commands.

    I assume you are using some sort of EventAggregator? I love what you are showing here for registering the listeners and would like some closure on the big picture.