DEV Community

What is Dependency Injection?

Milecia on November 01, 2018

There's too much jargon in the web development world. It's honestly surprising that we even understand each other. (do we really though?) That's wh...
Collapse
 
gypsydave5 profile image
David Wickes • Edited

The core of dependency injection, the reason we do it at all, is to make a static map of service objects.

While this is nice, it's really not the core of dependency injection. The reason why you want to do dependency injection at all is:

  • To help make code testable
  • Separate our concerns
  • Allow our code to be re-used

Take a look at

especially at the end.

Collapse
 
dwayne profile image
Dwayne Crooks

Yes! It's basically passing parameters to functions. More generally, it's about making your dependencies explicit versus implicit. Read my comment below to see what I mean and to view Python code that drives the point home.

import sys

def getc()
  c = sys.stdin.read(1)

  if not c:
    raise Exception('unexpected EOF')

  return c

In the code above I'm implicitly depending on standard input. So standard input is a dependency of the function. Among other things it makes that code harder to test.

The code is okay but one way in which it can be improved is by making the dependency on standard input explicit. Here's how:

import sys

def getc(input=sys.stdin)
  c = input.read(1)

  if not c:
    raise Exception('unexpected EOF')

  return c

Pass the dependency as an argument which makes it explicit. The function now takes a file like object which I defaulted to standard input since that would be the typical use case.

What have we gained? The code is much easier to test and understand because you know what depends on what. It's dependencies are explicit.

Passing your dependencies via arguments to functions is one way to "inject your dependencies", hence the term "dependency injection".

If you want to see how it helps with testing in a real project then you can read these examples from my Python Whitespace interpreter project:

Collapse
 
joshcheek profile image
Josh Cheek

Dependency injection is basically passing parameters to a function. It really is that simple. The reason that we like to do this is so we can keep a separation of responsibilities in the code. Are you surprised? It's not a framework and it doesn't have to be anything fancy. You can do dependency injection using constructors or a setter method.

πŸ‘†truth

Collapse
 
iam_ashfaque profile image
Ashfaque Mohammed

Hi Milecia, I have a query. What is the basic difference between Dependency Injection and Inversion of control. What is the need for both?

Collapse
 
xanderyzwich profile image
Corey McCarty
Collapse
 
flippedcoding profile image
Milecia

I'll have to write something about that soon. :)

Collapse
 
simoroshka profile image
Anna Simoroshka

Nice! Could you also explain inversion of control in simple words, please?

Collapse
 
setagana profile image
setagana

I'm not the original poster, but I'll take a stab at it:

The technique of dependency injection has a side effect of introducing the philosophy of inversion of control to your application. The philosophy of inversion of control is all about where decisions happen in your application, and IoC states that they should happen at a higher level of the application or in a point of central authority.

Say you have a logging class in an application where there is no inversion of control. Somewhere else in your application some logic determines that it's necessary to log something and calls your logging class informing it of the log level and the message to log.

Maybe your logging class has some internal logic which states that if the log level is Fatal; it's not only going to log to console, it's also going to send an email. In this situation there's no inversion of control. The decision (which is what IoC is all about) happens at a deep level of your application - inside the logging class which is called by something else.

When you decide to refactor your logging class for inversion of control in this situation, you start by saying I want to make the decision of whether or not to email at a higher point in my application than where it is now. One technique to use to achieve that goal is dependency injection - you could inject a communication strategy into your logging class when you make the call to log. Now your logging class doesn't make any decisions itself - it just interacts with the communication strategy that is injected without caring about the details inside it.

Dependency injection is probably the most widely known and widely used technique to introduce Inversion of Control, but there are others such as the service locator pattern. In this pattern your logging class is only aware of a single service locator for communication. It calls that service locator and passes on the same information every time, and the service locator decides which communication service to pass that information on to. The decision of communication strategy no longer sits in your logging class, but you're also not injecting any dependencies into the logging class.

Collapse
 
aftabksyed profile image
Aftab Syed

Nice article with easy to learn example

Collapse
 
nicko83931651 profile image
Nicko

Hi Milecia,

I look forward to reading your post, they seem to be very informative.

Thanks for sharing!

Collapse
 
flippedcoding profile image
Milecia

Thanks man! I'm really glad they actually help.