I’ve released a new version of my Unity Automapper today. It introduces what I’m finding to be a powerful feature of Unity that I call Multimapping which gives plug-in style capabilities in a very flexible manner.
Using Unity as an Collection Factory
Let’s say you had implemented a command pattern, and being a good developer you’d implemented your commands based on the ICommand interface: –
Now you want to write a command runner which iterates through all those commands. To register multiple items into Unity against the same interface, you need to give each registration a unique name and explicitly register each concrete manually. This also means tightly coupling the assembly that does the Unity registration to the one containing your commands.
Finally, you then can retrieve them from Unity either individually by name, or all at once through the handy ResolveAll<T>() method: –
But it’s still somewhat laborious to do the registrations manually. You have to pick names for each registration, then individually register them, and then explicitly call ResolveAll() to get them back – you can’t have the collection of them as a dependency. This is where the Automapper comes in
Unity Automapper Multimaps
Multimaps allow us to automatically register entire collections of concrete types against an individual interface, and then retrieve them extremely easily afterwards. Here’s the new features that allow us to do this.
You can now mark an interface as a Multimap. This tells the Automapper to seek out all implementations of that interface and to register them all against it.
That’s it. No need to explicitly register the Commands any more – just call RegisterAssemblies() or RegisterTypes() and they’ll get mapped to ICommand. You can now call the aforementioned ResolveAll() to get them all out.
Let’s say you always want this sort of behaviour, and don’t want to have to explicitly decorate your interfaces with the above attribute. There are now new overloads for the main entry points of the Automapper such as follows: –
MappingBehaviors help guide the behaviour of the mapper during auto-registration. In this case, we’ve told it to use Multimapping by default – so if we find more than one concrete type for any given interface, we’ll automatically use Multimapping behaviour. Otherwise, we fall back to standard behaviour. Of course, MappingBehaviors are flags, so you can mix and match any as you see fit.
Automatic Collection Registration
Thus far, if you want to get a handle to all of your multimap concretes, you have to get them via a call to ResolveAll(). With Automatic Collection Registration, you don’t even need to do that. This cool feature allows us to have dependencies that represent all the registrations against an interface simply by requesting an instance of IEnumerable<T>. First, perform mapping using the appropriate behaviour: –
Then, you can set up dependencies on other classes as follows: –
In this example, we are essentially telling Unity to pull out the mapping for the collection of all Commands. With Automatic Collection Registration, this is now possible – so you don’t have to explicitly call ResolveAll() any more!
The default behaviour for multimapping is that each registration in Unity will be a named after the full name of the concrete type. If that’s not for you, you can also guide the mapper to pick a particular name for a concrete type by placing the MapAsAttribute on it.
Multimapping is a powerful feature that gives us the ability to easily have factories generating entire collections of objects. By using the two mapping behaviours illustrated above, you can do this without any attributes and without the need to resolve to otherwise needed explicit method calls in Unity.
It should be pointed out that multimapping is completely optional. This is a non-breaking change, so if you don’t need it and call the API without providing any behaviours etc., nothing will change.
Hope you enjoy it – I’ve tried to keep the API as simple as possible; let me know if you have any suggestions.