When to use Dependency Injection

January 14th, 2009 · 19 Comments ·

by Miško Hevery

A great question from the reader…

The only thing that does not fully convince me in your articles is usage of Guice. I’m currently unable to see clearly its advantages over plain factories, crafted by hand. Do you recommend using of Guice in every single case? I strongly suspect, there are cases, where hand-crafted factories make a better fit than Guice. Could you comment on that (possibly at your website)?

I think this is multi-part question:

  1. Should I be using dependency-injection?
  2. Should I be using manual dependency-injection or automatic dependency-injection framework?
  3. Which automatic dependency-injection framework should I use?

Should I be using dependency-injection?

The answer to this question should be a resounding yes! We covered this many times how to think about the new-operator, singletons are liars, and of course the talk on dependency-injection.

Dependency injection is simply a good idea and it helps with: testability; maintenance; and bringing new people up to speed on new code-base. Dependency-injection helps you with writing good software whether it is a small project of one or large project with a team of collaborators.

Should I be using manual dependency-injection or automatic dependency-injection framework?

Whether or not to use a framework for dependency injection depends a lot on your preferences and the size of your project. You don’t get any additional magical powers by using a framework. I personally like to use frameworks on medium to large projects but stick to manual DI with small projects. Here are some arguments both ways to help you make a decision.

In favor of manual DI:

  • Simple: Nothing to learn, no dependencies.
  • No  reflection magic: In IDE it is easy to find out who calls the constructors.
  • Even developers who do not understand DI can follow and contribute to projects.

In favor of automatic DI framework:

  • Consistency: On a large team a lot can be said in doing things in consistent manner. Frameworks help a lot here.
  • Declarative: The wiring, scopes and rules of instantiation are declarative. This makes it easier to understand how the application is wired together and easier to change.
  • Less typing: No need to create the factory classes by hand.
  • Helps with end-to-end tests: For end-to-end tests we often need to replace key components of the application with fake implementations, an automated framework can be of great help.

Which automatic dependency-injection framework should I use?

There are three main DI frameworks which I am aware off: GUICE, Pico Container and Spring.

I work for Google, I have used GUICE extensively therefor my default recommendation will be GUICE. :-) However I am going to attempt to be objective about the differences. Keep in mind that I have not actually used the other ones on real projects.

Spring was first. As a result it goes far beyond DI and has everything and kitchen sink integrated into it which is very impressive. The DI part of Spring has some differences worth pointing out. Unlike GUICE or Pico, Spring uses XML files for configuration. Both are declarative but GUICE is compiled and as a result GUICE can take advantage of compiler type safety and generics, which I think is a great plus for GUICE.

Historically, Spring started with setter injection. Pico introduced constructor injection. Today, all frameworks can do both setter and constructor injection, but the developers using these frameworks still have their preferences. GUICE and Pico strongly prefer constructor  injection while Spring is in the setter injection camp. I prefer constructor injection but the reasons are better left for another post.

Personally, I think all of the three have been around for a while and have proven themselves extensively, so no matter which one you chose you will benefit greatly from your decision. All three frameworks have been heavily influenced by each other and on a macro level are very similar.

(I personally would not chose Spring because XML and setter injection puts me off. However I am looking forward to using Pico on my next open-source project so that i can become more objective about the differences.)

Your milage may very.

Tags: Advice

19 responses so far ↓

  • Chris F // Jan 14, 2009 at 2:06 pm

    Your arguments against Spring are invalid.  Spring does not force you to use XML configuration and has annotations that can do the same things.  Also, Spring in no way is “in the setter injection camp.”  Simply because they support it doesn’t mean they force it.  You can solely use constructor-injection if you so desire, Spring won’t complain.

  • Colin Sampaleanu // Jan 14, 2009 at 2:24 pm

    Your post is not very accurate about Spring…Spring actually has had quite extensive annotation based dependency injection capabilities since Spring 2.0, which came out around Nov 2007. Both XML and annotation-based dependency injection are “full citizens” in Spring, and the nice thing is you can mix and match and use one or the other or both. The annotation based functionality in Spring is arguably quite a bit more powerful than GUICE’s, since that concept of qualifiers is stronger, and you can also do things like use annotation-based DI on one particular object, but then override as needed with XML. So it’s trivial to do things like inject one instance of a class with one dependency, and another instance of that class with another one entirely.Regards,Colin

  • Colin Sampaleanu // Jan 14, 2009 at 2:25 pm

    Sorry, meant to say Spring 2.5, above, not 2.0. The date is correct though…Colin

  • John Smith // Jan 14, 2009 at 3:17 pm

    Nothing is forcing you to use setter based injection or XML in spring.  It will use constructor based injection and annotations.

  • André Faria Gomes // Jan 14, 2009 at 4:19 pm

    Hi Misko, good post!It’s important to remeber that XML configuration is now optional in Spring since you can use annotations instead.

  • sisuk // Jan 14, 2009 at 6:46 pm

    Agreed Andre.  Spring also does constructor injection.  I can understand some bias since Misko works for Google, but keep in mind Spring is still the 800 pound gorilla of DI frameworks.

  • Chris // Jan 15, 2009 at 1:24 am

    Spring 2.5′s documentation states “The Spring team generally advocates the usage of setter
    injection”.  I strongly favour constructor injection (for immutability) and dislike XML for configuration.  I’ve used both Spring and Guice extensively and I find Guice’s DI much nicer to use than Spring’s.

  • Tim // Jan 15, 2009 at 4:20 pm

    Doesn’t Pico predate Spring?  I’m pretty sure it does…

  • Jason // Jan 21, 2009 at 5:20 pm

    Misko,I would like see a post on why you favor constructor injection over setter injection.  This is a common question that comes up when developers are first introduced to DI.

  • Jason // Jan 21, 2009 at 5:23 pm

    Chris,I would like to know why you find Guice’s DI much nicer to use than Spring’s?  I hope you are comparing apples-to-apples and are comparing the use of spring annotations vs. Guice annotations because I would like to know how the annotation implementations differ.

  • Oh, your comments... // Jan 25, 2009 at 4:37 pm

    You will argue about which DI framework is better but what about THE subject: to use or not to use framework?I will agree that DI is the way to go, but I am sure this applies to the smallest applications as well. Nothing keeps the right order of things in application better than DI.But manual DI produces so much boilerplate code, that the clear benefits of using it starts to vanish. Few weeks ago I decided to do a first step in making my application better, because it looks like a spaghetti in many places. This is a large Swing application client for EJB3 back-end. I was asking myself exactly the same question: to choose a framework or not. I decided not to pick up framework and do manual DI. After few days I had a feeling that something goes wrong. Then I created a little, tiny Swing application  from scratch using (for the first time) Guice (excluding EJB3 – that was my first DI framework I dealt with in practice). When I finished it and moved back to my main job, the Swing client without DI framework, I felt like I there was missing something fundamental. One of the most brilliant features is the automatic creation of factories in Guice (called Providers, I am sure Spring has something simmilar). In Swing this is very common to ask for something new on every method call. Automatic creation of providers is so great. Without it, I would have to write like dozens, hundreds of dump factories and keep track of every single dependency, bacause factories need factories, those other factories propably need another factories. Terrible to keep the track manually.Another aspect is that without good framework there is always a tempation to create something using “new” in the bussiness code. You think – this class is a leaf, why shold I bother creating yet another factory for that. But when that leaf becomes a non-leaf, you end up with dozen places where you have to get rid of “new” and use your brand new, yet another factory… In Guice I am injecting everything, even if that is a leaf, because that costs me so little, just:@Injectprivate Provider<Something> somethingProvider;and later:Something = something.get();As soon as that “Something” becomes a non-leaf, everything still works. In my “Something” I can use injection and I do not care about proper wiring the stuff together. That was my $0.02 :) Regards,Witold SzczerbaP.S.Why everyone says: Spring does not need XML config, because since v2.5 it works with annotations.Maybe I;m wrong, but annotations are way too little to configure a module. In Guice, the counterpart Spring’s XML files are the com.google.inject.Module classes (by implementing the interface directly or by extending AbstractModule). I find it impossible to configure DI framework using the annotations and nothing more.

  • 1up4Developers » Blog Archive » TPW - Testando sistemas legados: manipulando dependências // Feb 19, 2009 at 8:48 am

    [...] da classe são delegados à outro objeto, ou normalmente um container de objetos, responsável por injetar as dependências nas instâncias das classes. Simples, não?! Mas isso será detalhado em outro [...]

  • Soapbox Rants and Raves » Good Reading… // May 2, 2009 at 7:34 am

    [...] having to put them into words! Please check out his posts, topics range from testability, to dependency injection, to Changing Developer [...]

  • Test Driven Development // Nov 16, 2009 at 6:26 pm

    [...] links to his site and there I found excellent articles that changed the way I approach programming. When to use Dependency Injection, Guide to Writing Testable Code and Dependency Injection Myth: Reference Passing are some of the [...]

  • Multi Tenant Architecture via Dependency Injection: Part 1 // Jul 11, 2010 at 1:51 pm

    [...] using a dependency injection framework, which is not the scope of this essay but can be enumerated here, for instance. Our example will use Ninject and ASP.NET MVC, although you could use any DI and [...]

  • Dileep // Oct 26, 2010 at 11:44 pm

    Hi Misko,
    Which and what type of Objects are Injectable ?

  • misko // Oct 27, 2010 at 9:08 am

    @Dileep,
    see: http://misko.hevery.com/2008/09/30/to-new-or-not-to-new/

  • Michal K // Jun 2, 2011 at 9:58 am

    Hi,

    I have a problem with DI and lazy initialization.
    Supose we have a code:

    class IdObject {
    Database db;
    Memcache mc;
    int id;
    String data;

    IdObject(int id, Database db, Memcache mc) {
    this.db = db;
    this.mc = mc;
    this.id = id;
    }

    int load_data() {
    this.data = mc.get(this.id);
    if (this.data === null) {
    this.data = db.get(this.id);
    }
    }
    }

    So using DI during creating IdObject we are creating both Database and Memcache objects, before we use load_data(), but moreover we create Database object even we need it, bacause in most cases mc.get() return data differentfrom null. So we have Database object and we have database connetction though we don’t need it.
    I’m PHP developer and after each script execution the connection is close. One of the solutions is connect to database when we use get() methods, but we must implement this also in others methods. Is the better solution to this problem?
    Thanks, and sorry for my poor English.

  • Jovan Ercic // Mar 15, 2012 at 3:03 am

    @Michal K,
    You could make IdObject depend on Database and Memcache factories. Then you request actual dependencies first time they are needed.

    Correct me if I’m wrong.

Leave a Comment