views:

3351

answers:

11

There have been several questions already posted with specific questions about dependency injection, such as when to use it, what frameworks are there for it. However, here's the newbie question:

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

Edit: While external links for followup reading are always appreciated, I'd like to encourage people to write as complete an answer here as possible, so that SO itself can be a good source to learn. I believe this is the intent of the site.

+10  A: 

Best place to start is Martin Fowler's article.

Ben Hoffstein
Martin Fowler is the man. I agree with Ben.
Josh
Martin Fowler IS the man, but if you don't know Java, you won't know what he's doing with his examples. (And if you know C#, you won't know what of what he's doing is DI magic, and what is jumping through the Java hoops.)
dnord
+2  A: 

From Wikipedia:

Dependency injection (DI) in Computer programming refers to the process of supplying an external dependency to a software component. It is a specific form of inversion of control where the concern being inverted is the process of obtaining the needed dependency.

Here's some good info:

http://en.wikipedia.org/wiki/Dependency_injection

http://en.wikipedia.org/wiki/Inversion_of_control

Ian P
+1  A: 

Here's a video explaining DI in context of Java

http://crazybob.org/2007/06/introduction-to-guice-video-redux.html

And then how guice does DI in Java.

http://code.google.com/p/google-guice/

Pyrolistical
+1  A: 

The google testing blog does a good job of explaining the benefits of dependency injection with regards to unit testing:

How to think about the new operator

Michael
+37  A: 

Basically, instead of having your objects creating a dependency or asking a factory object to make one for them, you pass the needed dependencies in to the constructor, and you make it somebody else's problem (an object further up the dependency graph, or a dependency injector that builds the dependency graph). A dependency as I'm using it here is any other object the current object needs to hold a reference to.

One of the major advantages of dependency injection is that it can make testing lots easier. Suppose you have an object which in it's constructor does something like:

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

This can be troublesome when all you want to do is run some unit tests on SomeClass, especially if myObject is something that does complex disk or network access. So now you're looking at mocking myObject but also somehow intercepting the factory call. Hard. Instead pass the object in as an argument to the constructor. Now you've moved the problem away elsewhere, but testing can become lots easier. Just make a dummy myObject and pass that in. The constructor would now look a bit like:

public SomeClass (MyClass myObject) {
    this.myObject = myObject;
}

Most people can probably work out the other problems that might arise when not using dependency injection while testing. Like classes that do too much work in their constructors etc. Most of this is stuff I picked up on the google testing blog, to be perfectly honest...

wds
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
+2  A: 

Probably dupe of this question

http://stackoverflow.com/questions/45191/ioc-explain-and-more-important-when-to-use-it#45197

Also SO has plenty of questions and answers about IoC/DI. I'm closing this question as dupe.

But feel free to open it again if you really think that those information is not sufficient.

aku
A: 

From the top of my head DI is about decoupling

c.sokun
+9  A: 

Dependency Injection is a practice where objects are designed in a manner where they receive instances of the objects from other pieces of code, instead of constructing them internally. This means that any object implementing the interface which is required by the object can be substituted in without changing the code, which simplifies testing, and improves decoupling.

For example, consider these clases:

public class PersonService {
  public void addManager( Person employee, Person newManager ) { ... }
  public void removeManager( Person employee, Person oldManager ) { ... }
  public Group getGroupByManager( Person manager ) { ... }
}

public class GroupMembershipService() {
  public void addPersonToGroup( Person person, Group group ) { ... }
  public void removePersonFromGroup( Person person, Group group ) { ... }
}

In this example, the implementation of PersonService::addManager and PersonService::removeManager would need an instance of the GroupMembershipService in order to do its work. Without Dependency Injection, the traditional way of doing this would be to instantiate a new GroupMembershipService in the constructor of PersonService and use that instance attribute in both functions. However, if the constructor of GroupMembershipService has multiple things it requires, or worse yet, there are some initialization "setters" that need to be called on the GroupMembershipService, the code grows rather quickly, and the PersonService now depends not only on the GroupMembershipService but also everything else that GroupMembershipService depends on. Furthermore, the linkage to GroupMembershipService is hardcoded into the PersonService which means that you can't "dummy up" a GroupMembershipService for testing purposes, or to use a strategy pattern in different parts of your application.

With Dependency Injection, instead of instantiating the GroupMembershipService within your PersonService, you'd either pass it in to the PersonService constructor, or else add a Property (getter and setter) to set a local instance of it. This means that your PersonService no longer has to worry about how to create a GroupMembershipService, it just accepts the ones it's given, and works with them. This also means that anything which is a subclass of GroupMembershipService, or implements the GroupMembershipService interface can be "injected" into the PersonService, and the PersonService doesn't need to know about the change.

Adam N
Preets
+1  A: 

See my discussion on Dependency Injection Here.

Kevin S.
+58  A: 

The best definition I found so far is one by James Shore:

"Dependency Injection" is a 25-dollar term for a 5-cent concept. [...] Dependency injection means giving an object its instance variables. [...].

There is an article by Martin Fowler that may prove useful too.

Dependency injection is basically providing the objects that an object needs (its dependencies) instead of having it construct them itself. It's a very useful technique for testing, since it allows dependencies to be mocked or stubbed out.

Dependencies can be injected into objects by many means. One can even use specialized dependency injection frameworks to do that, but they certainly aren't obligatory. You don't need those frameworks to have dependency injection. Instantiating and passing objects (dependencies) explicitly to is just as good an injection as injection by a framework.

Thiago Arrais
That one liner is the best explanation.
Unknown
Thanks - this makes perfect sense. It turns out I've used DI before and just didn't know what it was called. The term "dependency injection" makes it sound like it must be complicated.
Andy West
+1  A: 

One of the nicest explanation I've ever read about DI is from Google's Guice (pronounced as juice)

http://code.google.com/p/google-guice/wiki/Motivation?tm=6

Raj