Monday, August 4, 2008

Understanding Different Types of Dependency Injection

There are threemain types of DI:
• Interface injection (Type 1 IoC)
• Setter injection (Type 2 IoC)
• Constructor injection (Type 3 IoC)
Of these, setter injection and constructor injection are widely accepted and supported by
most IoC containers.
How It Works
For comparison, it’s better to introduce the DI types in order of their popularity and efficiency,
rather than by the type number.
Setter Injection (Type 2 IoC)
Setter injection is themost popular type of DI and is supported bymost IoC containers. The
container injects dependency via a settermethod declared in a component. For example,
ReportService can implement setter injection as follows:
package com.apress.springrecipes.report;
public class ReportService {
private ReportGenerator reportGenerator;
public void setReportGenerator(ReportGenerator reportGenerator) {
this.reportGenerator = reportGenerator;
}
...
}
The container has to inject dependencies by calling the settermethods after instantiating

public class Container {
public Container() {
...
ReportService reportService = new ReportService();
reportService.setReportGenerator(reportGenerator);
components.put("reportService", reportService);
}
...
}
Setter injection is popular for its simplicity and ease of use sincemost Java IDEs support
automatic generation of settermethods. However, there are someminor issues with this type.
The first is that, as a component designer, you cannot be sure that a dependency will be
injected via the settermethod. If a component user forgets to inject a required dependency,
the evil NullPointerException will be thrown and it will be hard to debug. But the good news
is that some advanced IoC containers (e.g., the Spring IoC container) can help you to check for
particular dependencies during component initialization.
Another shortcoming of setter injection has to do with code security. After the first injection,
a dependencymay still bemodified by calling the settermethod again, unless you have
implemented your own securitymeasures to prevent this. The carelessmodification of
dependenciesmay cause unexpected results that can be very hard to debug.
Constructor Injection (Type 3 IoC)
Constructor injection differs fromsetter injection in that dependencies are injected via a constructor
rather than settermethods. This type of injection, too, is supported bymost IoC
containers. For example, ReportServicemay accept a report generator as a constructor argument.
But if you do it this way, the Java compiler will not add a default constructor for this
class, because you have defined an explicit one. The common practice is to define a default
constructor explicitly for code compatibility.

No comments: