design patterns - without - What is dependency injection?




java dependency injection without spring (20)

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?


What is dependency Injection?

Dependency Injection(DI) means to decouple the objects which are dependent on each other. Say object A is dependent on Object B so the idea is to decouple these object from each other. We don’t need to hard code the object using new keyword rather sharing dependencies to objects at runtime in spite of compile time. If we talk about

How Dependency Injection works in Spring:

We don’t need to hard code the object using new keyword rather define the bean dependency in the configuration file. The spring container will be responsible for hooking up all.

Inversion of Control (IOC)

IOC is a general concept and it can be expressed in many different ways and Dependency Injection is one concrete example of IOC.

Two types of Dependency Injection:

  1. Constructor Injection
  2. Setter Injection

1. Constructor-based dependency injection:

Constructor-based DI is accomplished when the container invokes a class constructor with a number of arguments, each representing a dependency on other class.

public class Triangle {

private String type;

public String getType(){
    return type;
 }

public Triangle(String type){   //constructor injection
    this.type=type;
 }
}
<bean id=triangle" class ="com.test.dependencyInjection.Triangle">
        <constructor-arg value="20"/>
  </bean>

2. Setter-based dependency injection:

Setter-based DI is accomplished by the container calling setter methods on your beans after invoking a no-argument constructor or no-argument static factory method to instantiate your bean.

public class Triangle{

 private String type;

 public String getType(){
    return type;
  }
 public void setType(String type){          //setter injection
    this.type = type;
  }
 }

<!-- setter injection -->
 <bean id="triangle" class="com.test.dependencyInjection.Triangle">
        <property name="type" value="equivialteral"/>

NOTE: It is a good rule of thumb to use constructor arguments for mandatory dependencies and setters for optional dependencies. Note that the if we use annotation based than @Required annotation on a setter can be used to make setters as a required dependencies.


This is the most simple explanation about Dependency Injection and Dependency Injection Container I have ever seen:

Without Dependency Injection

  • Application needs Foo (e.g. a controller), so:
  • Application creates Foo
  • Application calls Foo
    • Foo needs Bar (e.g. a service), so:
    • Foo creates Bar
    • Foo calls Bar
      • Bar needs Bim (a service, a repository, …), so:
      • Bar creates Bim
      • Bar does something

With Dependency Injection

  • Application needs Foo, which needs Bar, which needs Bim, so:
  • Application creates Bim
  • Application creates Bar and gives it Bim
  • Application creates Foo and gives it Bar
  • Application calls Foo
    • Foo calls Bar
      • Bar does something

Using a Dependency Injection Container

  • Application needs Foo so:
  • Application gets Foo from the Container, so:
    • Container creates Bim
    • Container creates Bar and gives it Bim
    • Container creates Foo and gives it Bar
  • Application calls Foo
    • Foo calls Bar
      • Bar does something

Dependency Injection and dependency Injection Containers are different things:

  • Dependency Injection is a method for writing better code
  • a DI Container is a tool to help injecting dependencies

You don't need a container to do dependency injection. However a container can help you.


I found this funny example in terms of loose coupling:

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 us for...?

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.

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;
  }
}

Source: Understanding dependency injection


All the above answers are good, my aim is to explain the concept in a simple way so that anyone without a programming knowledge can also understand concept

Dependency injection is one of the design pattern that help us to create complex systems in a simpler manner.

We can see a wide variety of application of this pattern in our day to day life. Some of the examples are Tape recorder, VCD, CD Drive etc.

The above image is an image of Reel-to-reel portable tape recorder, mid-20th century. Source.

The primary intention of a tape recorder machine is to record or playback sound.While designing a system it require a reel to record or playback sound or music. we can place the reel inside the machine or we can provide a hook for the reel where it can be placed.if we opt for the second one that is placing a hook for reel, we are getting an added benefit of playing any music by changing the reel. and also reducing the function playing whatever in the reel.

The main benefits we achieved by using dependency injection.

  • High cohesion and loose coupling.
  • Externalizing dependency and looking only on responsibility.
  • Making things as components and to combine to form a large systems with high capabilities.
  • It helps to develop high quality components since they are independently developed they are properly tested.
  • It helps to replace the component with another if one fails.

Now a days these concept forms the basis of well known frameworks in programming world. The Spring Angular etc are the well-known software frameworks built on the top of this concept

Dependency injection is a pattern used to create instances of objects that other objects rely upon without knowing at compile time which class will be used to provide that functionality or simply the way of injecting properties to an object is called dependency injection.

Example for Dependency injection

Previously we are writing code like this

Public MyClass{
 DependentClass dependentObject
 /*
  At somewhere in our code we need to instantiate 
  the object with new operator  inorder to use it or perform some method.
  */ 
  dependentObject= new DependentClass();
  dependentObject.someMethod();
}

With Dependency injection, the dependency injector will take off the instantiation for us

Public MyClass{
 /* Dependency injector will instantiate object*/
 DependentClass dependentObject

 /*
  At somewhere in our code we perform some method. 
  The process of  instantiation will be handled by the dependency injector
 */ 

  dependentObject.someMethod();
}

You can also read

Difference between Inversion of Control & Dependency Injection


What is Dependency Injection (DI)?

As others have said, Dependency Injection(DI) removes the responsibility of direct creation, and management of the lifespan, of other object instances upon which our class of interest (consumer class) is dependent (in the UML sense). These instances are instead passed to our consumer class, typically as constructor parameters or via property setters (the management of the dependency object instancing and passing to the consumer class is usually performed by an Inversion of Control (IoC) container, but that's another topic).

DI, DIP and SOLID

Specifically, in the paradigm of Robert C Martin's SOLID principles of Object Oriented Design, DI is one of the possible implementations of the Dependency Inversion Principle (DIP). The DIP is the D of the SOLID mantra - other DIP implementations include the Service Locator, and Plugin patterns.

The objective of the DIP is to decouple tight, concrete dependencies between classes, and instead, to loosen the coupling by means of an abstraction, which can be achieved via an interface, abstract class or pure virtual class, depending on the language and approach used.

Without the DIP, our code (I've called this 'consuming class') is directly coupled to a concrete dependency and is also often burdened with the responsibility of knowing how to obtain, and manage, an instance of this dependency, i.e. conceptually:

"I need to create/use a Foo and invoke method `GetBar()`"

Whereas after application of the DIP, the requirement is loosened, and the concern of obtaining and managing the lifespan of the Foo dependency has been removed:

"I need to invoke something which offers `GetBar()`"

Why use DIP (and DI)?

Decoupling dependencies between classes in this way allows for easy substitution of these dependency classes with other implementations which also fulfil the prerequisites of the abstraction (e.g. the dependency can be switched with another implementation of the same interface). Moreover, as others have mentioned, possibly the most common reason to decouple classes via the DIP is to allow a consuming class to be tested in isolation, as these same dependencies can now be stubbed and/or mocked.

One consequence of DI is that the lifespan management of dependency object instances is no longer controlled by a consuming class, as the dependency object is now passed into the consuming class (via constructor or setter injection).

This can be viewed in different ways:

  • If lifespan control of dependencies by the consuming class needs to be retained, control can be re-established by injecting an (abstract) factory for creating the dependency class instances, into the consumer class. The consumer will be able to obtain instances via a Create on the factory as needed, and dispose of these instances once complete.
  • Or, lifespan control of dependency instances can be relinquished to an IoC container (more about this below).

When to use DI?

  • Where there likely will be a need to substitute a dependency for an equivalent implementation,
  • Any time where you will need to unit test the methods of a class in isolation of its dependencies,
  • Where uncertainty of the lifespan of a dependency may warrant experimentation (e.g. Hey, MyDepClass is thread safe - what if we make it a singleton and inject the same instance into all consumers?)

Example

Here's a simple C# implementation. Given the below Consuming class:

public class MyLogger
{
   public void LogRecord(string somethingToLog)
   {
      Console.WriteLine("{0:HH:mm:ss} - {1}", DateTime.Now, somethingToLog);
   }
}

Although seemingly innocuous, it has two static dependencies on two other classes, System.DateTime and System.Console, which not only limit the logging output options (logging to console will be worthless if no one is watching), but worse, it is difficult to automatically test given the dependency on a non-deterministic system clock.

We can however apply DIP to this class, by abstracting out the the concern of timestamping as a dependency, and coupling MyLogger only to a simple interface:

public interface IClock
{
    DateTime Now { get; }
}

We can also loosen the dependency on Console to an abstraction, such as a TextWriter. Dependency Injection is typically implemented as either constructor injection (passing an abstraction to a dependency as a parameter to the constructor of a consuming class) or Setter Injection (passing the dependency via a setXyz() setter or a .Net Property with {set;} defined). Constructor Injection is preferred, as this guarantees the class will be in a correct state after construction, and allows the internal dependency fields to be marked as readonly (C#) or final (Java). So using constructor injection on the above example, this leaves us with:

public class MyLogger : ILogger // Others will depend on our logger.
{
    private readonly TextWriter _output;
    private readonly IClock _clock;

    // Dependencies are injected through the constructor
    public MyLogger(TextWriter stream, IClock clock)
    {
        _output = stream;
        _clock = clock;
    }

    public void LogRecord(string somethingToLog)
    {
        // We can now use our dependencies through the abstraction 
        // and without knowledge of the lifespans of the dependencies
        _output.Write("{0:yyyy-MM-dd HH:mm:ss} - {1}", _clock.Now, somethingToLog);
    }
}

(A concrete Clock needs to be provided, which of course could revert to DateTime.Now, and the two dependencies need to be provided by an IoC container via constructor injection)

An automated Unit Test can be built, which definitively proves that our logger is working correctly, as we now have control over the dependencies - the time, and we can spy on the written output:

[Test]
public void LoggingMustRecordAllInformationAndStampTheTime()
{
    // Arrange
    var mockClock = new Mock<IClock>();
    mockClock.Setup(c => c.Now).Returns(new DateTime(2015, 4, 11, 12, 31, 45));
    var fakeConsole = new StringWriter();

    // Act
    new MyLogger(fakeConsole, mockClock.Object)
        .LogRecord("Foo");

    // Assert
    Assert.AreEqual("2015-04-11 12:31:45 - Foo", fakeConsole.ToString());
}

Next Steps

Dependency injection is invariably associated with an Inversion of Control container(IoC), to inject (provide) the concrete dependency instances, and to manage lifespan instances. During the configuration / bootstrapping process, IoC containers allow the following to be defined:

  • mapping between each abstraction and the configured concrete implementation (e.g. "any time a consumer requests an IBar, return a ConcreteBar instance")
  • policies can be set up for the lifespan management of each dependency, e.g. to create a new object for each consumer instance, to share a singleton dependency instance across all consumers, to share the same dependency instance only across the same thread, etc.
  • In .Net, IoC containers are aware of protocols such as IDisposable and will take on the responsibility of Disposing dependencies in line with the configured lifespan management.

Typically, once IoC containers have been configured / bootstrapped, they operate seamlessly in the background allowing the coder to focus on the code at hand rather than worrying about dependencies.

The key to DI-friendly code is to avoid static coupling of classes, and not to use new() for the creation of Dependencies

As per above example, decoupling of dependencies does require some design effort, and for the developer, there is a paradigm shift needed to break the habit of newing dependencies directly, and instead trusting the container to manage dependencies.

But the benefits are many, especially in the ability to thoroughly test your class of interest.

Note : The creation / mapping / projection (via new ..()) of POCO / POJO / Serialization DTOs / Entity Graphs / Anonymous JSON projections et al - i.e. "Data only" classes or records - used or returned from methods are not regarded as Dependencies (in the UML sense) and not subject to DI. Using new to project these is just fine.


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 object externally, and you make it somebody else's problem. This "someone" is either an object further up the dependency graph, or a dependency injector (framework) 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 its 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 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;
}

This is one style of dependency injection - via the constructor. Several mechanisms are possible.

  • As noted in the comments, one common alternative is to define a do-nothing constructor, and have the dependencies injected via property setters (h/t @MikeVella).
  • Martin Fowler documents a third alternative (h/t @MarcDix), where classes explicitly implement an interface for the dependencies they wish injected.

When not using dependency injection (such as in classes that do too much work in their constructors etc.), it tends to become much harder to isolate components in unit testing.

Back in 2013 when I wrote this answer, this was a major theme on the Google Testing Blog. This remains the biggest advantage to me, as you may not always need the extra flexibility in your run-time design (for instance, for service locator or similar patterns), but you do often need to be able to isolate your classes during testing.


Dependency Injection (DI) is part of Dependency Inversion Principle (DIP) practice, which is also called Inversion of Control (IoC). Basically you need to do DIP because you want to make your code more modular and unit testable, instead of just one monolithic system. So you start identifying parts of the code that can be separated from the class and abstracted away. Now the implementation of the abstraction need to be injected from outside of the class. Normally this can be done via constructor. So you create a constructor that accepts the abstraction as a parameter, and this is called dependency injection (via constructor). For more explanation about DIP, DI, and IoC container you can read Here


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.


Dependency injection is the heart of the concept related with Spring Framework.While creating the framework of any project spring may perform a vital role,and here dependency injection come in pitcher.

Actually,Suppose in java you created two different classes as class A and class B, and whatever the function are available in class B you want to use in class A, So at that time dependency injection can be used. where you can crate object of one class in other,in the same way you can inject an entire class in another class to make it accessible. by this way dependency can be overcome.

DEPENDENCY INJECTION IS SIMPLY GLUING TWO CLASSES AND AT THE SAME TIME KEEPING THEM SEPARATE.


Doesn't "dependency injection" just mean using parameterized constructors and public setters?

James Shore's article shows the following examples for comparison.

Constructor without dependency injection:

public class Example { 
  private DatabaseThingie myDatabase; 

  public Example() { 
    myDatabase = new DatabaseThingie(); 
  } 

  public void doStuff() { 
    ... 
    myDatabase.getData(); 
    ... 
  } 
} 

Constructor with dependency injection:

public class Example { 
  private DatabaseThingie myDatabase; 

  public Example(DatabaseThingie useThisDatabaseInstead) { 
    myDatabase = useThisDatabaseInstead; 
  }

  public void doStuff() { 
    ... 
    myDatabase.getData(); 
    ... 
  } 
}


I know there are already many answers, but I found this very helpful: http://tutorials.jenkov.com/dependency-injection/index.html

No Dependency:

public class MyDao {

  protected DataSource dataSource =
    new DataSourceImpl("driver", "url", "user", "password");

  //data access methods...
  public Person readPerson(int primaryKey) {...}

}

Dependency:

public class MyDao {

  protected DataSource dataSource = null;

  public MyDao(String driver, String url, String user, String
 password){
    this.dataSource = new DataSourceImpl(driver, url, user, password);
  }

  //data access methods...
  public Person readPerson(int primaryKey)
  {...}

}

Notice how the DataSourceImpl instantiation is moved into a constructor. The constructor takes four parameters which are the four values needed by the DataSourceImpl. Though the MyDao class still depends on these four values, it no longer satisfies these dependencies itself. They are provided by whatever class creating a MyDao instance.


I would propose a slightly different, short and precise definition of what Dependency Injection is, focusing on the primary goal, not on the technical means (following along from here):

Dependency Injection is the process of creating the static, stateless graph of service objects, where each service is parametrised by its dependencies.

The objects that we create in our applications (regardless if we use Java, C# or other object-oriented language) usually fall into one of two categories: stateless, static and global “service objects” (modules), and stateful, dynamic and local “data objects”.

The module graph - the graph of service objects - is typically created on application startup. This can be done using a container, such as Spring, but can also be done manually, by passing parameters to object constructors. Both ways have their pros and cons, but a framework definitely isn’t necessary to use DI in your application.

One requirement is that the services must be parametrised by their dependencies. What this means exactly depends on the language and approach taken in a given system. Usually, this takes the form of constructor parameters, but using setters is also an option. This also means that the dependencies of a service are hidden (when invoking a service method) from the users of the service.

When to use? I would say whenever the application is large enough that encapsulating logic into separate modules, with a dependency graph between the modules gives a gain in readability and explorability of the code.


In simple words dependency injection (DI) is the way to remove dependencies or tight coupling between different object. Dependency Injection gives a cohesive behavior to each object.

DI is the implementation of IOC principal of Spring which says "Don't call us we will call you". Using dependency injection programmer doesn't need to create object using the new keyword.

Objects are once loaded in Spring container and then we reuse them whenever we need them by fetching those objects from Spring container using getBean(String beanName) method.


Let's imagine that you want to go fishing:

  • Without dependency injection, you need to take care of everything yourself. You need to find a boat, to buy a fishing rod, to look for bait, etc. It's possible, of course, but it puts a lot of responsibility on you. In software terms, it means that you have to perform a lookup for all these things.

  • With dependency injection, someone else takes care of all the preparation and makes the required equipment available to you. You will receive ("be injected") the boat, the fishing rod and the bait - all ready to use.


Let's try simple example with Car and Engine classes, any car need an engine to go anywhere, at least for now. So below how code will look without dependency injection.

public class Car
{
    public Car()
    {
        GasEngine engine = new GasEngine();
        engine.Start();
    }
}

public class GasEngine
{
    public void Start()
    {
        Console.WriteLine("I use gas as my fuel!");
    }
}

And to instantiate the Car class we will use next code:

Car car = new Car();

The issue with this code that we tightly coupled to GasEngine and if we decide to change it to ElectricityEngine then we will need to rewrite Car class. And the bigger the application the more issues and headache we will have to add and use new type of engine.

In other words with this approach is that our high level Car class is dependent on the lower level GasEngine class which violate Dependency Inversion Principle(DIP) from SOLID. DIP suggests that we should depend on abstractions, not concrete classes. So to satisfy this we introduce IEngine interface and rewrite code like below:

    public interface IEngine
    {
        void Start();
    }

    public class GasEngine : IEngine
    {
        public void Start()
        {
            Console.WriteLine("I use gas as my fuel!");
        }
    }

    public class ElectricityEngine : IEngine
    {
        public void Start()
        {
            Console.WriteLine("I am electrocar");
        }
    }

    public class Car
    {
        private readonly IEngine _engine;
        public Car(IEngine engine)
        {
            _engine = engine;
        }

        public void Run()
        {
            _engine.Start();
        }
    }

Now our Car class is dependent on only the IEngine interface, not a specific implementation of engine. Now, the only trick is how do we create an instance of the Car and give it an actual concrete Engine class like GasEngine or ElectricityEngine. That's where Dependency Injection comes in.

   Car gasCar = new Car(new GasEngine());
   gasCar.Run();
   Car electroCar = new Car(new ElectricityEngine());
   electroCar.Run();

Here we basically inject(pass) our dependency(Engine instance) to Car constructor. So now our classes have loose coupling between objects and their dependencies, and we can easily add new types of engines without changing the Car class.

The main benefit of the Dependency Injection that classes are more loosely coupled, because they do not have hard-coded dependencies. This follows the Dependency Inversion Principle, which was mentioned above. Instead of referencing specific implementations, classes request abstractions (usually interfaces) which are provided to them when the class is constructed.

So in the end Dependency injection is just a technique for achieving loose coupling between objects and their dependencies. Rather than directly instantiating dependencies that class needs in order to perform its actions, dependencies are provided to the class (most often) via constructor injection.

Also when we have many dependencies it is very good practice to use Inversion of Control(IoC) containers which we can tell which interfaces should be mapped to which concrete implementations for all our dependencies and we can have it resolve those dependencies for us when it constructs our object. For example, we could specify in the mapping for the IoC container that the IEngine dependency should be mapped to the GasEngine class and when we ask the IoC container for an instance of our Car class, it will automatically construct our Car class with a GasEngine dependency passed in.

UPDATE: Watched course about EF Core from Julie Lerman recently and also liked her short definition about DI.

Dependency injection is a pattern to allow your application to inject objects on the fly to classes that need them, without forcing those classes to be responsible for those objects. It allows your code to be more loosely coupled, and Entity Framework Core plugs in to this same system of services.


The best analogy I can think of is the surgeon and his assistant(s) in an operation theater, where the surgeon is the main person and his assistant who provides the various surgical components when he needs it so that the surgeon can concentrate on the one thing he does best (surgery). Without the assistant the surgeon has to get the components himself every time he needs one.

DI for short, is a technique to remove a common additional responsibility (burden) on components to fetch the dependent components, by providing them to it.

DI brings you closer to the Single Responsibility (SR) principle, like the surgeon who can concentrate on surgery.

When to use DI : I would recommend using DI in almost all production projects ( small/big), particularly in ever changing business environments :)

Why : Because you want your code to be easily testable, mockable etc so that you can quickly test your changes and push it to the market. Besides why would you not when you there are lots of awesome free tools/frameworks to support you in your journey to a codebase where you have more control.


The best definition I've 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 (such as constructor injection or setter injection). One can even use specialized dependency injection frameworks (e.g. Spring) to do that, but they certainly aren't required. You don't need those frameworks to have dependency injection. Instantiating and passing objects (dependencies) explicitly is just as good an injection as injection by framework.


The whole point of Dependency Injection (DI) is to keep application source code clean and stable:

  • clean of dependency initialization code
  • stable regardless of dependency used

Practically, every design pattern separates concerns to make future changes affect minimum files.

The specific domain of DI is delegation of dependency configuration and initialization.

Example: DI with shell script

If you occasionally work outside of Java, recall how source is often used in many scripting languages (Shell, Tcl, etc., or even import in Python misused for this purpose).

Consider simple dependent.sh script:

#!/bin/sh
# Dependent
touch         "one.txt" "two.txt"
archive_files "one.txt" "two.txt"

The script is dependent: it won't execute successfully on its own (archive_files is not defined).

You define archive_files in archive_files_zip.sh implementation script (using zip in this case):

#!/bin/sh
# Dependency
function archive_files {
    zip files.zip "[email protected]"
}

Instead of source-ing implementation script directly in the dependent one, you use an injector.sh "container" which wraps both "components":

#!/bin/sh 
# Injector
source ./archive_files_zip.sh
source ./dependent.sh

The archive_files dependency has just been injected into dependent script.

You could have injected dependency which implements archive_files using tar or xz.

Example: removing DI

If dependent.sh script used dependencies directly, the approach would be called dependency lookup (which is opposite to dependency injection):

#!/bin/sh
# Dependent

# dependency look-up
source ./archive_files_zip.sh

touch         "one.txt" "two.txt"
archive_files "one.txt" "two.txt"

Now the problem is that dependent "component" has to perform initialization itself.

The "component"'s source code is neither clean nor stable because every changes in initialization of dependencies requires new release for "components"'s source code file as well.

Last words

DI is not as largely emphasized and popularized as in Java frameworks.

But it's a generic approach to split concerns of:

  • application development (single source code release lifecycle)
  • application deployment (multiple target environments with independent lifecycles)

Using configuration only with dependency lookup does not help as number of configuration parameters may change per dependency (e.g. new authentication type) as well as number of supported types of dependencies (e.g. new database type).


To make Dependency Injection concept simple to understand. Let's take an example of switch button to toggle(on/off) a bulb.

Without Dependency Injection

Switch needs to know beforehand which bulb I am connected to (hard-coded dependency). So,

Switch -> PermanentBulb //switch is directly connected to permanent bulb, testing not possible easily

Switch(){
PermanentBulb = new Bulb();
PermanentBulb.Toggle();
}

With Dependency Injection

Switch only knows I need to turn on/off whichever Bulb is passed to me. So,

Switch -> Bulb1 OR Bulb2 OR NightBulb (injected dependency)

Switch(AnyBulb){ //pass it whichever bulb you like
AnyBulb.Toggle();
}

Modifying James Example for Switch and Bulb:

public class SwitchTest { 
  TestToggleBulb() { 
    MockBulb mockbulb = new MockBulb(); 

    // MockBulb is a subclass of Bulb, so we can 
    // "inject" it here: 
    Switch switch = new Switch(mockBulb); 

    switch.ToggleBulb(); 
    mockBulb.AssertToggleWasCalled(); 
  } 
}

public class Switch { 
  private Bulb myBulb; 

  public Switch() { 
    myBulb = new Bulb(); 
  } 

  public Switch(Bulb useThisBulbInstead) { 
    myBulb = useThisBulbInstead; 
  } 

  public void ToggleBulb() { 
    ... 
    myBulb.Toggle(); 
    ... 
  } 
}`




terminology