# Dependency Injection

## Summary


The recommended practice in creating complex software is to adopt a modular design. Functionality is decomposed into modules or classes, each doing something specific and exposing their services via well-defined interfaces. This implies that one module will often depend on other modules or components of the system.

Dependencies among modules can lead to code that's tightly coupled and less maintainable. **Dependency Injection (DI)** is therefore used to resolve dependencies at *runtime* rather than at *compile time*. Objects that have dependencies will not themselves create those dependencies. They will instead rely on an another entity to create and inject those dependencies. 

Dependency Injection is considered a design pattern and not a framework. It's one way of implementing a more general software concept called **Inversion of Control (IoC)**. It's also part of **SOLID Design Principles**.

## Discussion

### Could you explain dependency injection with an example?

Let's consider a class `XRateForecaster` that forecasts currency exchange rates. It accesses a database to obtain historical rates. It accesses a remote service for real-time rates. It also invokes an algorithm that does the forecasting. This class therefore has three dependencies that need to be fulfilled for it to work properly.

Without DI, `XRateForecaster` will probably instantiate these dependencies on its own. This would work but what happens if these dependencies are modified in future? `XRateForecaster` would need to be modified. Worse still, `XRateForecaster` is tightly coupled with its dependencies. We can't do any unit testing with it without resolving its dependencies.

With DI, the dependent class does not construct its dependencies. The dependencies are injected into it at runtime. Obviously, moving legacy code to this design pattern implies that code has to be refactored. It should be noted that DI doesn't remove dependencies. It merely separates the creation of dependencies from their consumption. 


### What are the benefits of using dependency injection?

DI loosens the tight coupling between modules, classes or services. Code maintainability improves. Code can be reused. Because dependencies are injected at runtime, a different mock implementation can be injected for the purpose of unit testing. In fact, unit testing is one of the big benefits of adopting DI.  

With DI, different implementations of the dependencies can be supplied. In other words, the dependent class can be written in abstraction without worrying about concrete implementations of its dependencies. Dependencies are no longer scattered across the app. They can be centralized in a container, or specified in an XML file. 

*Dependency carrying* happens when a class instantiates a service it doesn't need but one of its dependencies needs. DI solves this problem. Jakob Jenkov describes many situations where DI is useful. 


### What are some potential problems of using dependency injection?

Because dependencies are resolved at runtime, errors in dependencies cannot be caught at compile time. Tracing dependencies can be difficult. In languages such as Java or C#, there can be an explosion of data types. Programmers can become overdependent on DI frameworks. Learning a specific DI framework and managing the configuration can be extra work. 

Using DI for the sake of using it is wrong. If you're never going to use another implementation or configuration, then it's best to avoid DI. One of the principles of object-oriented programming is encapsulation but DI break encapsulation. DI brings some of the implementation details, the dependencies, out to the interface. 

DI can be done without containers. In fact, it's been said that containers add more lines of code and even more files if XML configuration is used. It adds unnecessary complexity. Worse still, using global singleton as injector causes problems. 


### What are the different types of dependency injection?

There are three common ways of injecting dependencies: 

    + **Constructor Injection**: Dependency is passed to the object via its constructor that accepts an interface as an argument. A concrete class object is bound to the interface handle. This is typically used if the dependent object has to use the same concrete class for its lifetime.
    + **Method Injection**: A.k.a. interface-based injection. Dependency is passed to the object via a method. This is useful if a different concrete object needs to be used at different times. For example, if the dependency is a notification, sometimes this may sent as an SMS, and other times as an email for the same dependent object.
    + **Property Injection**: A.k.a. setter injection. If the dependency is selected and invoked at different places, we can set the dependency via a property exposed by the dependent object, which can then invoke it later.An alternative to the above is *Service Locator*, which abstracts away the job of resolving dependencies. However, some identify this too as a form of dependency injection since the locator itself has to be injected into the dependent object. 


### Are there frameworks for dependency injection?

While it's possible to implement dependency injection without any frameworks, what if your dependencies themselves depend on other dependencies? Frameworks simplify the job by providing what's called an **IoC Container** or **Dependency Injection Container (DIC)**. 

A container will create the dependent object along with its dependencies. Writing container code can also get tedious since we need to create one for each dependent class. This is where frameworks come in by providing generic DICs that can read in configuration information about dependencies, say, from an XML file. 

Spring Framework, PicoContainer, HiveMind, XWork, Java EE6 CDI, Weld, Google Guice, Salta, Glassfish HK2, Dagger and Managed Extensibility Framework (MEF) are example DI frameworks. For .NET, DI frameworks include Spring.NET, Castle Windsor, Unity, StructureMap, Autofac and Ninject. 

In Spring, there are at least three ways of doing DI: XML, annotations, pure Java code. Angular has its own DI mechanism using `@Injectable` decorator. ASP.NET Core does it via its built-in service container, `IServiceProvider` Google Guice uses `@Inject` constructor annotation. For Android, there's Dagger, RoboGuice, ButterKnife and Android Annotation. 


### Could you share some tips on dependency injection for beginners?

Passing in too many dependencies is an indication that the class is doing too much. It's better to split the class into multiple classes, each having a specific responsibility. Injecting dependencies but not using them or passing them to other classes is another anti-pattern. Inject interfaces, not implementations. Know what services need to be exposed, mark them public and keep all others private. If you use configuration files (XML, YAML, etc.) keep them readable. 

A common anti-pattern is to invoke a singleton static container to instantiate services from within a dependent class. This is the service locator approach. It's using IoC container without doing DI. Instead, inject an interface into the constructor. If you use containers, register all components and resolve at the root component. 

DI is not the only way to achieve IoC. Other ways include factory pattern, template method pattern, strategy pattern and service locator pattern. However, for example, with factory pattern the class still instantiates the factory and dependencies from within rather than being injected from the outside. 

## Milestones

Aug  
1994

Robert Martin notes that object-oriented design on its own will not make code robust, maintainable and reusable. The pattern of interdependencies across subsystems matters too. A module's intent should not dependent on its details. He uses the term *Dependency Inversion*. In June 1995 he defines the *Principle of Dependency Inversion*,

> Details should depend upon abstractions. Abstractions should not depend upon details.

1998

The term *Inversion of Control (IoC)* is coined by Brian Foote. He implies that frameworks don't have the power. They are extensible skeletons and their behaviour is tailored by methods supplied by client code or application. In essence, components are externally managed. 

1999

Stefano Mazzocchi and others propose Java Apache Server Framework, later called Avalon. This uses IoC as one of its fundamental design principles. Avalon may be credited with popularizing IoC. According to Mazzocchi, IoC is really about isolation, modularity and reuse. The need to inject dependencies is an effect, not the cause. 

2003

Spring Framework is released. Spring was conceived by Rod Johnson a year earlier and released as part of his book on the framework. It uses DI and IoC containers, although he states that the term DI was coined in late 2003. Also in 2003, names type 1/2/3/4 are renamed to today's familiar names interface/setter/constructor injection. 

2004

Martin Fowler coins the term *Dependency Injection* in an article. He explains that it's a specific form of Inversion of Control (IoC). He also compares it to an alternative pattern called *Service Locator*.