Making Unity mappings easier with Reflection


Nothing really magical here, but I was playing around with Unity the other day – I wanted to do some dependency inversion – and got to thinking about how one generally implements their type mappings.

There are usually two ways: –

  • Do your mapping in a config file
  • Use code-driven mappings i.e. in C#

In my experience, I have found the latter somewhat easier to develop with i.e. easier to read and follow C# than a chunky XML file, compile time safety of mappings, and unless you need post-compile flexibility, XML files are unnecessary.

The only downside is that in order to use mappings in code, you have to have a reference to your concrete types that you’re going to map to in order to get to them at compile time. I didn’t want to do that in my case, but still wanted to use code rather than XML for my mappings. So I ended up writing a fairly simple bit of reflection-based code to pull in the mappings at runtime: –

UnityContainer container = new UnityContainer();

var requiredInterfaces = new[]
{
    typeof(IDocumentReader),
    typeof(IDocumentWriter)
};

var implementationAssemblies = Directory.GetFiles(".", "*.dll");

var mappings = from assemblyName in implementationAssemblies
               from type in Assembly.LoadFrom(assemblyName).GetTypes()
               from requiredInterface in requiredInterfaces
               where requiredInterface.IsAssignableFrom(type)
               select new {
                   Interface = requiredInterface,
                   Instance = Activator.CreateInstance(type)
               };

foreach (var mapping in mappings)
    container.RegisterInstance(mapping.Interface, mapping.Instance);

So, with this approach we first create a simple Unity container. Then we have a list of required interfaces – this could of course be abstracted away somewhere else – which we will map to concrete types.

Then we simply get a list of all DLLs in our current folder – obviously this is a simplistic example; you could only look for ones with a particular name, or have a fixed list in code, or perhaps even abstract away to a settings file etc..

With this list of assemblies we just look through for any type which implements one of the interfaces found before and then register that mapping with Unity. Hey presto – now you get automatic mappings done, no coding or config files required.

Obviously this is a simplistic example overall – if you want to have fine-grained control over your DI this won’t work that well! But this code probably passes the 80/20 rule i.e. 80% of the time this is the sort of thing would probably work just fine.

You could even take it to the next step and remove the list of required interfaces, and instead just find any custom interfaces that you have written and to search for resolutions of them (perhaps tag them with an attribute or such?).

Advertisements

2 thoughts on “Making Unity mappings easier with Reflection

  1. Great article – very much appreciated.

    The only corection I had to make is that the interface type itself isn’t being excluded in the mappings collection, which produces a “cannot create an instance of an interface” exception at run time. Altering the ‘where’ statement to become “where requiredInterface.IsAssignableFrom(type) && type != requiredInterface” solves the problem.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s