views:

575

answers:

2

It's sometimes necessary when using dependency injection to provide the parameters to use in the constructor. This is something that's supported in Unity (and other dependency injection containers), so that when it tries to create an instance of the type, it can provide your arguments as parameters in the constructor.

My question is: is this approach desirable?

Within an interface it is not possible to specify which parameters an implementing class must have. By specifying the parameters to Unity, you are assuming that the implementing class has these parameters, and you are placing implicit constraints over future implementing classes. These constraints cannot be communicated through the interface.

So, is this is flaw in how interfaces themselves are specified (in .NET), eg. should it be possible to specify constructor signatures? Or has this feature (of being able to provide constructor parameters) been included in Unity due to some other need?

The only real workable approach (to me) seems to be use a factory to create the implementing classes, and do dependency injection on the factory.

I appreciate my question here might not be clear, so I'll ask it slightly differently: what's the best way to do dependency injection on a class which has a constructor requiring parameters?

(I do not believe this question to be subjective, as there should probably be a single design pattern for this type of dependency injection.)

EDIT:

I should add, that my main problem is that I may create a new implementing class which has additional constructor parameters (where the constructor parameters are not things that can be created by unity).

A: 

The responsibility of IoC containers (say Unity) is to connect interfaces with concrete implementations. That means your container must know the interface and how to create the object that implements the interface. Using constructor injection is perfectly legal and the recommended way. Unity will create the concrete implementation when your application requests an interface through the Resolve() method. The Unity container itself is the factory that creates your objects, you use Unity because you don't want to implement those factories by yourself.

Christian Rodemeyer
But where the constructor requires instance variables, I need to provide these to Unity myself. But the interface does not specify that I need these parameters, so what if i create a concrete implementation of the interface which has additional parameters in the constructor?
David_001
+2  A: 

I'm not sure where you got the idea that constructor injection does not fit with DI. I'd say that the real situation is the opposite of that: constructor injection is one of the most common patterns utilised to achieve dependency injection - I'd go as far as saying that it is the most common pattern, and that view is certainly backed up by the fact that that majority of Inversion of Control containers (DI containers) use constructor injection as their preferred mechanism.

StructureMap for example has a core, very specific support for constructor injection where it will pick the constructor with the most parameters as the constructor used for dependency resolution.

What you are saying by using the constructor injection pattern is that "I am removing the hard coded dependencies within my class by specifying them as parameters passed into the constructor - my class cannot be instantiated without these dependencies". Of course, the first half of that statement is the essence of DI, but the second half enforces this more.

Dependencies are an implementation detail that should be able to be changed easily, providing a flexible, loosely coupled solution. They are about the how, not the what. Interfaces specify the what. So I'd say that your suggestion of specifying dependencies in interfaces actually goes against the concept of dependency injection.

And as far as your statement about factories - this is exactly what IOC containers are - great big factories that take care of a solution's dependency tree, so you don't need to care.

Edit

I think maybe you are asking about the case where you want to provide a non-dependency constructor parameter, such as an id for a referenced entity, or an initial state enum?

I personally don't see a problem with an IOC container allowing for this. It is still initial state of your class and hence the rules for the creation of that state need to be explicitly expressed. It can mean that you sometimes need more references to your IOC container that you might like, but it is not a horrible enough situation to abandon the other benefits of counstructor injection.

David Hall
You are correct in your edit - I am referring to the parameters in the constructor which are specific class instances or value types, not things that the IOC container will resolve by creating new instances.
David_001