Telling Unity Which Constructor to Use when Initializing a Class
I’ve been using Unity for a fair amount of time now, and it has really grown on me. In my previous post, I linked to a solution which used it (although the rest of the project didn’t depend on that particular Inversion of Control container). For basic dependency injection, it has been working really well for me. However, I recently ran into an interesting issue. Say I have a class Foo (implementing IFoo) that I want resolved at runtime. Foo has the following constructors:
public interface IFoo
{
// ...
}
class Foo : IFoo
{
public Foo(IDependency dependency)
: this(dependency, 5)
{ }
public Foo(IDependency dependency, int someNumberWhoseDefaultIs5)
{
// ...
}
// ...
}
By default, Unity will select the most complicated constructor and attempt to resolve all of the dependencies given in the parameters. That’s fine for interfaces that it can resolve, but what about that int? It’s clear that we want it to default to 5, but Unity will ignore the first and try to resolve the second, causing a runtime error on resolution.
Unity provides a relatively simple solution to this problem. You can tell Unity which constructor to resolve to when registering a type. In this example, we would like Unity to resolve the first constructor, so that our default value of 5 is used (and no exceptions are thrown, of course):
UnityContainer unityContainer = new UnityContainer();
unityContainer.Configure<InjectedMembers>().
ConfigureInjectionFor<Foo>
(new InjectionConstructor(unityContainer.Resolve<IDependency>()));
unityContainer.RegisterType<IFoo, Foo>();
(As you can see, I prefer to use code to register types as opposed to configuration files.) InjectionConstructor takes in a params object[] array, since it does not know what parameters the constructor has. It will then take what is given and try to find a matching constructor. Now Unity will resolve the constructor we want it to resolve. As you can see from the example, IDependency will still be resolved via UnityContainer, but when it calls the first constructor, it will also use our default value of 5.
This brings up a question: Where should we put default values? I like to keep them in the class they belong to, but we could also put them where we register types with Unity. If we kept up this practice, then we’d have all of our default values in one place, but we wouldn’t necessarily know what the values mean. We could extract variables, but then the registration file(s) would get messy, and I like to keep those as simple as possible.
