IoC: Constructors with two parameters of the same type

Nov 12, 2014 at 4:10 PM
Hi,

When using Unity for IOC, I am relying on Constructor Injection when resolving my classes.

I happen to have a class the has a dependency on 2 other classes, say, Class1 and Class2. Both Class1 and Class2 are derived from BaseClass. which implements IBaseClass. So my class ctor looks like this:

MyClass(IBaseClass class1, IBaseClass class2)

How can I register Class1 and Class2 in the container so that MyClass is resolved with the correct concreate implementation?

Do I have to define two new interfaces for Class1 and Class2 so that resolve can differentiate between the two implementation?

Thanks for your help.

Graham
Nov 12, 2014 at 5:13 PM
Edited Jun 18, 2015 at 5:03 AM
Do I have to define two new interfaces for Class1 and Class2 so that resolve can differentiate between the two implementation?
No. Definitely no. Don't do that. :)

There are a few ways to do what you want. If it's OK to deal with the concrete classes directly you can just tell Unity to inject the correct concrete implementation of IBaseClass. This approach is simple and Class1 and Class2 will also have their dependencies injected:
IUnityContainer container = new UnityContainer();

container.RegisterType<MyClass>(new InjectionConstructor(
    typeof(Class1), typeof(Class2)));

var myClass = container.Resolve<MyClass>();

If you want (need) to deal with the interfaces then you would have to register multiple mappings between IBaseClass and the implementation classes using a named registration:
IUnityContainer container = new UnityContainer();

// Register IBaseClass mappings by name
container.RegisterType<IBaseClass, Class1>(typeof(Class1).Name);
container.RegisterType<IBaseClass, Class2>(typeof(Class2).Name);

// Resolve IBaseClass by name to inject the correct implementation
container.RegisterType<MyClass>(new InjectionConstructor(
    new ResolvedParameter<IBaseClass>(typeof(Class1).Name),
    new ResolvedParameter<IBaseClass>(typeof(Class2).Name)));

var myClass = container.Resolve<MyClass>();

Another approach that can work is an injection factory but that is not required in this scenario (it's overkill).

~~
Randy Levy
entlib.support@live.com
Enterprise Library support engineer
Support How-to
Marked as answer by GrahamAtSDA on 11/12/2014 at 11:04 PM
Nov 13, 2014 at 7:04 AM
Perfect!

Thanks Randy.