Take the 2-minute tour ×
Programmers Stack Exchange is a question and answer site for professional programmers interested in conceptual questions about software development. It's 100% free, no registration required.

I'm new to dependency injection and I have a few questions about which style I shouldI use in my applications. I've just read Inversion of Control Containers and the Dependency Injection pattern by Martin Fowler, but I can't get the practical difference between constructor, setter and interface injection.

It seems to me that the reasons for using one over the other are just a matter of code cleaning and/or clarity. What is the difference? Are there any strong advantages or disadvantages for using one over the other, or is it just what I've stated before?

In my opinion, constructor injection is the most intuitive of all, as well as interface injection is the least. In the other hand, setter injection is a middle term, but, are you supposed to be able to change the instance of the dependency object you initially injected? Does this style of injection guarantees that the object which needs the dependency will always have it injected? I believe not, but please correct me if I'm wrong.

share|improve this question

migrated from stackoverflow.com Mar 16 '13 at 22:21

This question came from our site for professional and enthusiast programmers.

    
Not sure what else you have found or read along the way. I found some similar threads here and here. I'm new myself, and would be curious to the answers you may get :) –  user1766760 Mar 16 '13 at 20:27
    
@user1766760 you should help me then here, my question is being voted to be closed, two more votes and it's done!!! Vote the question up or something, I don't know what can be done to avoid closing. –  ecampver Mar 16 '13 at 20:36
    
erm... I'm new to SO myself so I'm not too sure how I can help / why it is being voted to close (I don't see any indication??). If I venture a guess, perhaps it's not a specific programming question but more of a discussion? –  user1766760 Mar 16 '13 at 20:55
    
You might like to expand the question a bit. Dependency injection is one form of "Inversion of Control". There are alternatives. A useful but ripe for abuse alternative is Service Location for example. –  Ian Mar 17 '13 at 11:11

2 Answers 2

up vote 8 down vote accepted

Constructor Injection has the advantage that it makes the dependency explicit and forces the client to provide an instance. It can also guarantee that the client cannot change the instance later. One (possible) downside is that you have to add a parameter to your constructor.

Setter Injection has the advantage that it doesn't require adding a parameter to the constructor. It also doesn't require the client to set the instance. This is useful for optional dependencies. This may also be useful if you want the class to create, for example, a real data repository by default, and then in a test you can use the setter to replace it with a testing instance.

Interface Injection, as far as I can tell, is not much different than setter injection. In both cases you are (optionally) setting a dependency that can be changed later.

Ultimately it is a matter of preference and whether or not a dependency is required. Personally, I use constructor injection almost exclusively. I like that it makes the dependencies of a class explicit by forcing the client to provide an instance in the constructor. I also like that the client cannot change the instance after the fact.

Often times, my only reason for passing in two separate implementations is for testing. In production, I may pass in a DataRepository, but in testing, I would pass in a FakeDataRepository. In this case I'll usually provide two constructors: one with no parameters, and another that accepts a IDataRepository. Then, in the constructor with no parameters, I will chain a call to the second constructor and pass in a new DataRepository().

Here's an example in C#:


public class Foo
{
  private readonly IDataRepository dataRepository;

  public Foo() : this(new DataRepository())
  {
  }

  public Foo(IDataRespository dataRepository)
  {
    this.dataRepository = dataRepository;
  }
}

This is known as Poor Man's Dependency Injection. I like it because in production client code, I don't need to repeat myself by having several repeated statements that look like

var foo = new Foo(new DataRepository());
However, I can still pass in an alternate implementation for testing. I realize that with Poor Man's DI I'm hardcoding my dependency, but that's acceptable for me since I mostly use DI for testing.

share|improve this answer
    
thanks, that's quite close to what I understand, but still, is there any scenario where you can't use constructor injection? –  ecampver Mar 17 '13 at 6:35
1  
You probably wouldn't want to use constructor injection for optional dependencies. I can't think of any other reasons not to use it. –  jhewlett Mar 17 '13 at 6:49
    
I use property setter injection specifically to populate some configuration classes which include a large number of values. I don't use it anywhere else. I'm always a bit dubious about making a case for optional parameters because there's a good chance it's an infraction of the single responsibility rule. Of course rules are meant to be broken, so ... –  Ian Mar 17 '13 at 11:09
    
@jhewlett - that's fantastic, I've been looking for a good simple stubbing technique for unit testing that doesn't over complicate my solution - and I think this is it :) –  LachlanB Mar 18 '13 at 0:04

The differences between constructor and setter injection are already adequately described above, so I won't elaborate further on them.

Interface injection is a more advanced form of injection that is useful because it allows the dependency to be decided at the moment it is used rather than during initialisation of the object that will use it. This allows a number of useful options:

  • The dependency could be scoped differently to the object it is injected in; for instance you can use interface injection to provide an object for which one exists per user session or per thread to a global singleton. Each time the object needs the dependency, it will call the getter method provided by the framework, and this can return different results depending on the situation in which it is called.

  • It allows for lazy initialization -- there is no need for the dependency to be initialized until it is about to be used

  • It allows dependencies to be loaded from a cached copy when they exist or reinitialised when they don't (e.g. using a SoftReference in Java).

Obviously advanced techniques like this have downsides; in this case, the main problem is that code becomes less clear (classes used in your code become abstract, and there is no obvious concrete implementation of them, which can be confusing if you aren't used to it) and you become more dependent on your dependency injection framework (it's still possible to instantiate your objects manually, of course, but it is harder than with other injection styles).

share|improve this answer

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.