Categories
dependency-injection design-patterns language-agnostic terminology

What is dependency injection?

3472

There have been several questions already posted with specific questions about dependency injection, such as when to use it and what frameworks are there for it. However,

What is dependency injection and when/why should or shouldn’t it be used?

7

  • See my discussion on Dependency Injection Here.

    – Kevin S.

    Sep 25, 2008 at 8:27

  • 42

    I agree with the comments regarding links. I can understand you may want to reference someone else. But at least add why you are linking them and what makes this link better than the other links I could get by using google

    Jun 1, 2009 at 0:27

  • @AR: Technically, Dependency Injection is not a special form of IoC. Rather, IoC is one technique that is used to provide Dependency Injection. Other techniques could be used to provide Dependency Injection (although IoC is the only one in common use), and IoC is used for many other problems as well.

    Aug 28, 2009 at 12:50

  • 153

    Regarding links, remember that they often disappear one way or another. There is a growing number of dead links in SO answers. So, no matter how good the linked article is, it’s no good at all if you can’t find it.

    – DOK

    Oct 28, 2010 at 16:26

  • Vojta Jina on Dependency Injection youtu.be/_OGGsf1ZXMs. The first part.

    – Jichao

    Mar 8, 2015 at 17:57

2111

Dependency Injection is passing dependency to other objects or framework( dependency injector).

Dependency injection makes testing easier. The injection can be done through constructor.

SomeClass() has its constructor as following:

public SomeClass() {
    myObject = Factory.getObject();
}

Problem:
If myObject involves complex tasks such as disk access or network access, it is hard to do unit test on SomeClass(). Programmers have to mock myObject and might intercept the factory call.

Alternative solution:

  • Passing myObject in as an argument to the constructor
public SomeClass (MyClass myObject) {
    this.myObject = myObject;
}

myObject can be passed directly which makes testing easier.

  • One common alternative is defining a do-nothing constructor. Dependency injection can be done through setters. (h/t @MikeVella).
  • Martin Fowler documents a third alternative (h/t @MarcDix), where classes explicitly implement an interface for the dependencies programmers wish injected.

It is harder to isolate components in unit testing without dependency injection.

In 2013, when I wrote this answer, this was a major theme on the Google Testing Blog. It remains the biggest advantage to me, as programmers not always need the extra flexibility in their run-time design (for instance, for service locator or similar patterns). Programmers often need to isolate the classes during testing.

11

  • 27

    Acknowledging that Ben Hoffstein’s referenceto Martin Fowler’s article is necessary as pointing a ‘must-read’ on the subject, I’m accepting wds’ answer because it actually answers the question here on SO.

    – AR.

    Sep 26, 2008 at 16:55

  • 131

    +1 for explanation and motivation: making the creation of objects on which a class depends someone else’s problem. Another way to say it is that DI makes classes more cohesive (they have fewer responsibilities).

    Nov 29, 2012 at 18:26

  • 14

    You say the dependency is passed “in to the constructor” but as I understand it this isn’t strictly true. It’s still dependency injection if the dependency is set as a property after the object has been instantiated, correct?

    Aug 7, 2013 at 19:52


  • 2

    @MikeVella Yes, that is correct. It makes no real difference in most cases, though properties are generally a bit more flexible. I will edit the text slightly to point that out.

    – wds

    Aug 8, 2013 at 15:14

  • 3

    One of the best answers I’ve found so far, thus I’m really interested in improving it. It’s missing a description of the third form of dependency injection: Interface injection.

    – Marc Dix

    May 27, 2016 at 21:27


2111

Dependency Injection is passing dependency to other objects or framework( dependency injector).

Dependency injection makes testing easier. The injection can be done through constructor.

SomeClass() has its constructor as following:

public SomeClass() {
    myObject = Factory.getObject();
}

Problem:
If myObject involves complex tasks such as disk access or network access, it is hard to do unit test on SomeClass(). Programmers have to mock myObject and might intercept the factory call.

Alternative solution:

  • Passing myObject in as an argument to the constructor
public SomeClass (MyClass myObject) {
    this.myObject = myObject;
}

myObject can be passed directly which makes testing easier.

  • One common alternative is defining a do-nothing constructor. Dependency injection can be done through setters. (h/t @MikeVella).
  • Martin Fowler documents a third alternative (h/t @MarcDix), where classes explicitly implement an interface for the dependencies programmers wish injected.

It is harder to isolate components in unit testing without dependency injection.

In 2013, when I wrote this answer, this was a major theme on the Google Testing Blog. It remains the biggest advantage to me, as programmers not always need the extra flexibility in their run-time design (for instance, for service locator or similar patterns). Programmers often need to isolate the classes during testing.

11

  • 27

    Acknowledging that Ben Hoffstein’s referenceto Martin Fowler’s article is necessary as pointing a ‘must-read’ on the subject, I’m accepting wds’ answer because it actually answers the question here on SO.

    – AR.

    Sep 26, 2008 at 16:55

  • 131

    +1 for explanation and motivation: making the creation of objects on which a class depends someone else’s problem. Another way to say it is that DI makes classes more cohesive (they have fewer responsibilities).

    Nov 29, 2012 at 18:26

  • 14

    You say the dependency is passed “in to the constructor” but as I understand it this isn’t strictly true. It’s still dependency injection if the dependency is set as a property after the object has been instantiated, correct?

    Aug 7, 2013 at 19:52


  • 2

    @MikeVella Yes, that is correct. It makes no real difference in most cases, though properties are generally a bit more flexible. I will edit the text slightly to point that out.

    – wds

    Aug 8, 2013 at 15:14

  • 3

    One of the best answers I’ve found so far, thus I’m really interested in improving it. It’s missing a description of the third form of dependency injection: Interface injection.

    – Marc Dix

    May 27, 2016 at 21:27


780

I found this funny example in terms of loose coupling:

Source: Understanding dependency injection

Any application is composed of many objects that collaborate with each other to perform some useful stuff. Traditionally each object is responsible for obtaining its own references to the dependent objects (dependencies) it collaborate with. This leads to highly coupled classes and hard-to-test code.

For example, consider a Car object.

A Car depends on wheels, engine, fuel, battery, etc. to run. Traditionally we define the brand of such dependent objects along with the definition of the Car object.

Without Dependency Injection (DI):

class Car{
  private Wheel wh = new NepaliRubberWheel();
  private Battery bt = new ExcideBattery();

  //The rest
}

Here, the Car object is responsible for creating the dependent objects.

What if we want to change the type of its dependent object – say Wheel – after the initial NepaliRubberWheel() punctures?
We need to recreate the Car object with its new dependency say ChineseRubberWheel(), but only the Car manufacturer can do that.

Then what does the Dependency Injection do for us…?

When using dependency injection, objects are given their dependencies at run time rather than compile time (car manufacturing time).
So that we can now change the Wheel whenever we want. Here, the dependency (wheel) can be injected into Car at run time.

After using dependency injection:

Here, we are injecting the dependencies (Wheel and Battery) at runtime. Hence the term : Dependency Injection. We normally rely on DI frameworks such as Spring, Guice, Weld to create the dependencies and inject where needed.

class Car{
  private Wheel wh; // Inject an Instance of Wheel (dependency of car) at runtime
  private Battery bt; // Inject an Instance of Battery (dependency of car) at runtime
  Car(Wheel wh,Battery bt) {
      this.wh = wh;
      this.bt = bt;
  }
  //Or we can have setters
  void setWheel(Wheel wh) {
      this.wh = wh;
  }
}

The advantages are:

  • decoupling the creation of object (in other word, separate usage from the creation of object)
  • ability to replace dependencies (eg: Wheel, Battery) without changing the class that uses it(Car)
  • promotes “Code to interface not to implementation” principle
  • ability to create and use mock dependency during test (if we want to use a Mock of Wheel during test instead of a real instance.. we can create Mock Wheel object and let DI framework inject to Car)

6

  • 27

    The way I understand this is, instead of instantiating a new object as part of another object, we can inject said object when and if it is needed thus removing the first object’s dependency on it. Is that right?

    May 28, 2014 at 20:08

  • I have described this with a coffee shop example here:digigene.com/design-patterns/dependency-injection-coffeeshop

    – Ali Nem

    Nov 12, 2016 at 10:41

  • 13

    Really like this analogy because it’s plain English using a simple analogy. Say I’m Toyota, already spent too much financially and man power on making a car from design to rolling off the assemble line, if there are existing reputable tire producers, why should I start from scratch to make a tire manufacture division i.e. to new a tire? I don’t. All I have to do is to buy (inject via param) from them, install and wah-lah! So, coming back to programming, say a C# project needs to use an existing library/class, there are two ways to run/debug, 1-add reference to the entire project of this

    – Jeb50

    Aug 9, 2017 at 23:52

  • (con’t),.. external library/class, or 2-add it from the DLL. Unless we have to see what’s inside of this external class, adding it as DLL is a easier way. So option 1 is to new it, option 2 is pass it in as param. May not be accurate, but simple stupid easy to understand.

    – Jeb50

    Aug 9, 2017 at 23:56


  • 3

    @JeliBeanMachine (sorry for extremely late reply to a comment..) it’s not that we remove the first object’s dependency on the wheel object or battery object, it’s that we pass it the dependency, so that we can change the instance or implementation of the dependency. Before: Car has a hardcoded dependency on NepaliRubberWheel. After: Car has an injected dependency on instance of Wheel.

    Jan 3, 2018 at 15:43