Constructor Injection vs. Setter Injection

February 19th, 2009 · 31 Comments ·

by Miško Hevery

There seems to be two camps in dependency-injection: (1) The constructor-injection camp and (2) the setter-injection camp. Historically the setter-injection camp come from spring, whereas constructor-injection camp are from pico-container and GUICE. But lets leave the history behind and explore the differences in the strategies.

Setter-Injection

The basic-ideas is that you have a no argument-constructor which creates the object with “reasonable-defaults” . The user of the object can then call setters on the object to override the collaborators of the object in order to wire the object graph together or to replace the key collaborators with test-doubles.

Constructor-Injection

The basic idea with constructor-injection is that the object has no defaults and instead you have a single constructor where all of the collaborators and values need to be supplied before you can instantiate the object.

At first it may seem that setter injection is preferred since you have no argument constructors which will make it easy for you to create the object in production and test. However, there is one non-obvious benefit with constructor injection, which in my opinion makes it a winner. Constructor-injection enforces the order of initialization and prevents circular dependencies. With setter-injection it is not clear in which order things need to be instantiated and when the wiring is done. In a typical application there may be hundreds of collaborators with at least as many setter calls to wire them together. It is easy to miss a few setter calls when wiring the application together. On the other hand constructor-injection automatically enforces the order and completeness of the instantiated. Furthermore, when the last object is instantiated the wiring phase of your application is completed. This further allows me to set the collaborators as final which makes the code easier to comprehend if you know a given field will not change during the lifetime of the application.

Let’s look at an example as to how we would instantiate a CreditCardProcessor.

CreditCardProcessor processor 
        = new CreditCardProcessor();

Great I have instantiated CreditCardProcessor, but is that enough? No, I somehow need to know to call, setOfflineQueue(). This information is not necessarily obvious.

OfflineQueue queue = new OfflineQueue();
CreditCardProcessor processor 
        = new CreditCardProcessor();
processor.setOfflineQueue(queue);

Ok I have instantiated the OfflineQueue and remember to set the queue as a collaborator of the processor, but am I done? No, you need to set the database to both the queue and the processor.

Database db = new Database();
OfflineQueue queue = new OfflineQueue();
queue.setDatabase(db);
CreditCardProcessor processor 
        = new CreditCardProcessor();
processor.setOfflineQueue(queue);
processor.setDatabase(db);

But wait, you are not done you need to set the Username, password and the URL on the database.

Database db = new Database();
db.setUsername("username");
db.setPassword("password");
db.setUrl("jdbc:....");
OfflineQueue queue = new OfflineQueue();
queue.setDatabase(db);
CreditCardProcessor processor 
        = new CreditCardProcessor();
processor.setOfflineQueue(queue);
processor.setDatabase(db);

Ok, am I done now? I think so, but how do I know for sure? I know a framework will take care of it, but what if I am in a language where there is no framework, then what?

Ok, now let’s see how much easier this will be in the constructor-injection. Lets instantiate CreditCardPrecossor.

CreditCardProcessor processor 
        = new CreditCardProcessor(?queue?, ?db?);

Notice we are not done yet since CreditCardProcessor needs a queue and a database, so lets make those.

Database db = new Database(
        "username", "password", "jdbc:....");
OfflineQueue queue = new OfflineQueue(db);
CreditCardProcessor processor 
        = new CreditCardProcessor(queue, db);

Ok, every constructor parameter is accounted for, therefore we are done. No framework needed, to tell us that we are done. As an added bonus the code will not even compile if all of the constructor arguments are not satisfied. It is also not possible to instantiate things in the wrong order. You must instantiate Database before the OfflineQueue, since otherwise you could not make the compiler happy. I personally find the constructor-injection much easier to use and the code is much easier to read and understand.

Recently, I was building a Flex application and using the Model-View-Controller. Flex XML markup requires that components must have no argument constructors, therefore I was left with setter-injection as the only way to do dependency injection. After several views I was having hard time to keep all of the pieces wired together properly, I was constantly forgetting to wire things together. This made the debugging hard since the application appeared to be wired together (as there are reasonable defaults for your collaborators)  but the collaborators were of wrong instances and therefor the application was not behaving just right. To solve the issue, I was forced to abandon the  Flex XML as a way to instantiate the application so that I can start using the constructor-injection and these issues went away.

Tags: Uncategorized

31 responses so far ↓

  • Luke Lutman // Feb 19, 2009 at 11:39 am

    With constructor injection, how would you deal with a chicken-and-egg situation where two objects need to know about each other?

  • misko // Feb 19, 2009 at 12:15 pm

    Circular dependencies are a code smell. See here: http://misko.hevery.com/2008/08/01/circular-dependency-in-constructors-and-dependency-injection/

  • Pawel Zubkiewicz // Feb 19, 2009 at 1:50 pm

    Misko, I think you’ve insert wrong url in you answer.

  • Liam // Feb 19, 2009 at 3:52 pm

    I agree that Constructor dependency injection is much better than using setter injection, yet it does cause some problems with regards to factories. Though I must say I am a surprised after your previous article in which you want to pass nulls in constructors.

  • cory // Feb 19, 2009 at 7:25 pm

    @Liam, Why would it be a surprise to advocate both passing nulls and constructor injection? They are very complimentary, as you assured in a test environment that the unused collaborators will be null, not a “sane” default. Both practices also do a great job of keeping the work out of a constructor.

  • Witold Szczerba // Feb 20, 2009 at 2:45 am

    The constructor injection seems great, but then you have to write one extra class – the provider for  every non-singleton component which is rather not convinient. So what about something in between? Constructor and extra #init method? Constructor accepts  everything which is “managed” and extra #init method accepts runtime parameters. Or when you are forced to provide no-arg constructor (my example for this is the case with NetBeans GUI Builder) then you can create two init methods or one #init + field injection.

  • Witold Szczerba // Feb 20, 2009 at 2:50 am

    …of course, there is no need for extra provider/factory for constructor injection when all you have to pass to the constructor is “managed” (or registered? cannot find the right word for this).

  • Liam // Feb 20, 2009 at 3:42 am

    “Constructor and extra #init method” Well one of the reasons I believe constructor injection is much better is die to RAII; yet I am more a C++ programmer than a Java.

  • Liam // Feb 20, 2009 at 3:43 am

    “die” = “due” oops :)

  • igorbrejc.net » Fresh Catch For February 20th // Feb 20, 2009 at 7:02 am

    [...] Constructor Injection vs. Setter Injection [...]

  • Liam // Feb 20, 2009 at 6:20 pm

    @cory
    Misko gave a talk entitled “The Clean Code Talks — Inheritance, Polymorphism, & Testing” [1]
    In a nut shell:
    - By moving new operators from constructors into factories and injecting dependencies into constructors and wiring.
    - Using polymorphism for state dependant code.
    - Removes the need for runtime checks in code.
    If a parameter is in the constructor, it is of importance for the state of the class yet the null-ness state of the pointer can affect code for the class. If you are going to use a factory to call new operators and dependencies are then injected into this factory, then it has the appropriate knowledge and constructs accordingly. The factory should make the decision and possibly pass a mock object. Why pass a null? If you do then there is the possibility of code being littered with if(null pointer) then else … conditions. If it is important enough to the construction of the class, then it is important enough to mock the object and producing a clean code base which is easy to test.
    [1]http://www.youtube.com/watch?v=4F72VULWFvc&feature=channel_page

  • Integrazione JSF e Spring « A Place In The Queue // Mar 2, 2009 at 12:41 pm

    [...] tramite costruttore, che personalmente preferisco rispetto all’ approccio via setter. Questo articolo di Miško Hevery spiega i motivi della mia personalissima scelta :-) « [...]

  • Using (These) Anonymous Inner Classes is Probably Too Clever for Your Own Good at JAW Speak // Mar 10, 2009 at 9:33 pm

    [...] It uses setters. Setters allow your object to be constructed in an inconsistent state. There are some situations setters are fine (i.e. form backing objects) but often your code is more clear without setters. In this particular case the setters aren’t egregious, but I still consider them a smell and much more verbose way that constructor injection. Read more about the problem with setter injection here [...]

  • Constructor Injection vs Setter Injection « shaun smith // May 1, 2009 at 10:56 am

    [...] Constructor Injection vs Setter Injection Constructor vs Setter Injection – Constructor is Better Setter injection versus constructor injection and the use of required [...]

  • firefight // Jul 15, 2009 at 12:26 pm

    Nice article. I think the problem with your view of setter injection is that you have “reasonable defaults”. With Spring you do not have any reasonable defaults, they are null by default, so your app will fail quickly and obviously, rather then appear to work, if the setters are not called. It sounds like you were doing all of the setting in code once per object, rather then specifying them once per class, like you do in Spring.

    Personally I’m not fond of setter injection, either. I like my objects immutable if possible, and it just seems like a lot of extra code and configuration, that is rarely ever used to extend the application anyway.

  • Berlin Brown // Dec 18, 2009 at 8:31 am

    This is probably a stupid question, but how do you deal with constructor injection and too many arguments. Should we create everything and the kitchen sink objects and then pass that as our constructor?

  • Artur Ejsmont // Dec 30, 2009 at 9:59 am

    Hi there

    Im not sure yet how much i like constructor injection but i know i dont like setter injection. You should not be able to create non functioning object. Init methods and magic calls needed to make instance work are code smell as well i would say.

    The problem i would agree with is that in constructor injection you have no clear names for parameters (in some frameworks only order tells you what to insert) and if you have too many of them code begins to look bit nasty.

  • misko // Jan 1, 2010 at 10:59 am

    @Artur,

    Yes too many arguments in your constructor is a code smell. It means that your object has too many responsibilities and needs to be broken up.

  • Craig Harris // Jan 1, 2010 at 7:40 pm

    @Artur,

    The builder pattern would appear to solve many of the problems you are seeing.

  • marcus kielly // Mar 25, 2010 at 3:23 pm

    I tend to pass arguments in arrays if there are more than 3 arguments, and unpack the array in the constructor. Then again, I’m a filthy PHP coder…

  • Dependency Injection – The What And The How « Binary Thoughts : IEnumerable<T> // Jul 4, 2010 at 11:18 pm

    [...] very distinct styles of injection are Constructor Injection and Setter Injection.  Constructor injection takes dependencies using the constructor like the code above – it [...]

  • madhu // Aug 18, 2010 at 2:15 am

    We can not say constructor injection is better or setter injection is better. Both are having different values. Like constructor injection is good in because it provide ready to use in initialization object and object created is immutable. but in case of more number of parameter constructor injection is complicated and its better to prefer setter injection. similarily in case of similar type of parameter it requires more configuration but setter injection requires similar configuration. So we can say setter injection and constructor injection have different benefits and its not good idea to compare them.

  • Chandramohan P L // Sep 14, 2010 at 10:43 pm

    @Madhu,

    I tend to disagree with you. Ideally for a good OOD application, we should not have more than three parameters. If there are more parameters, it means that an object is having to many responsibilities.

  • mck // May 13, 2011 at 8:08 am

    I agree generally with a preference of constructor injection.

    But i think that this preference can lead to poor code. Nothing in the discussion between constructor vs setter injection will allude to this because constructor injection fails not against setter injection but against the bigger coding picture.

    This article goes into this in depth: http://tech.finn.no/2011/05/13/dependency-injection-with-constructors/

  • someguy // Aug 8, 2012 at 11:06 am

    @mck

    That article goes on a rant about some specific application and how the author feels that constructor injection would fail in his case. How about some concrete reasons why you would and wouldn’t want to use constructor injection instead?

    I understand that there are sometimes cases where constructor injection cannot be used, but to pretend like its never a good technique strikes me as ideological.

    I think most things have a place, and constructor injection is easily preferable to other types in a lot of cases. I’d love to hear some concrete examples of where it isn’t possible or isn’t preferable instead of empty rhetoric.

  • someguy // Aug 8, 2012 at 11:30 am

    In order to be more constructive, I think this article also offers a decent analysis of the different mechanisms of injection:

    http://blog.springsource.org/2007/07/11/setter-injection-versus-constructor-injection-and-the-use-of-required/

    There definitely ARE reasons not to use constructor injection in specific cases. But if you cannot find a technical reason to do so, I would think it would be preferable.

    Even if you don’t check for non-null collaborators you are likely to get a NPE upon instantiation which will point you directly at the problem.

  • Implementing Dependency Inversion in C# without increasing complexity « Javier Andres Caceres Alvis – C# para Windows Phone 7 // Sep 19, 2012 at 10:21 am

    [...] both patterns do the same that the strategy except by the fact that the injection is at runtime via constructor or setter. There are many ways to inject an implementation by runtime depending on the selected technology. [...]

  • Tom B // Oct 5, 2012 at 9:22 am

    You missed probably the biggest problem with setter injection: An object can exist in a non-complete state.

    Much like your arguments in “Constructor does real work”, where you mention “Object not fully initialized after the constructor finishes (watch out for initialize methods)” the same applies here. Setter injection allows for an incomplete object to exist in the system. Anything that uses that object cannot be guaranteed that the object is in the correct state to be used. This breaks encapsulation by essentially exposing implementation to the client code.

  • ravi // Oct 20, 2012 at 12:51 am

    in spring application both setter injection and constructor injection,then which injection will performed first ?why ?
    please give me explanation for me…….

  • James // Nov 20, 2012 at 12:49 am

    I always use setter one because of readability. This link also has some good points

  • Eric // Dec 20, 2012 at 9:45 pm

    My choice of setter vs constructor injection is situational, and I often will use both in the same object.

    Constructor injection: mandatory dependencies.
    Setter injection: optional dependencies.

    Granted, optional dependencies could be handled via constructor injection and a null parameter, but that becomes difficult as soon as you have more than one optional dependency.

    The most common scenario where I’ll utilize both is when some children of a parent class have a certain dependency while others do not. I’ll utilize constructor injection for the shared dependency so that the constructor signature is consistent among the classes (preserving the L of SOLID) and use setter injection for the dependencies not shared among the subclasses.

Leave a Comment