Making Unity work more like the others

I love MS Unity as an IoC container, it has some great features. Though I found it to function incorrectly at two points (it’s not that the path chosen by the Unity team is incorrect, I just want/excpect it to act differently).

The first thing that bothered me was the fact that Unity throws an exception when Resolve<T> is not able to resolve the given type: I’d prefer it to return null instead, hence most containers do that. The second, even more irritating point, was that ResolveAll<T> only returned the named instances/types instead of all registered types. In fact, Unity overwrites the default registration if your register a type multiple times. Eg:

would cause the MyClass1 registration to be removed. I’d like the MyClass1 to remain the default registration, and have ResolveAll<IMyInterface>() return both. I’m happy to tell you that it can be done!

When using an IoC container, it’s good practice to access it’s features through a generic wrapper class. For my projects, I use the wrapper from the Kigg source code. If you access the container through a wrapper after you configured your container, it’ll be easy to replace it with a different container in the future.

My wrapper class looks like this:

Though most methods are just direct wrappers for accessing the container itself, there are a few extra’s. For one, there’s the ResolveAll<T> method that returns both named and unnamed instances instead of only the named instances, that’s one problem fixed.

Secondly, you can see the Resolve methods use

if (Container.Configure<TypeTrackingExtension>().CanResolve(type, name))

It uses an UnityExtension to see if the Type can be resolved and it returns null if it can’t. This solution was provided by David Buksbaum in his blog post Type Tracking Extension for Unity. This extension is added to the container in this wrapper’s constructor.

I did modify David’s extension a little, to have it not overwrite the first registered type and to have CanResolve return true for types that can be initiated also (the original only returns true for types that have been registered). My version looks like this:

As you can see, I change the order of the event chain, by removing UnityDefaultBehaviorExtension from the Container, and then add it again later. This allows us to add a name to the type being registered. If a type is registered multiple times without a name given, a name is given in the form of a unique Guid

So now, if you do

classes will contain both MyClass1 and MyClass2!

Leave a Reply

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.