Tuesday, November 1, 2011

Different approaches for Dependency Injection (DI)

Objectives of dependency injection:

 Objectives of dependency injection

  1. To perform their functions, classes depend on other classes as units of reuse. These other classes need to be initialized and a lot of times need the caller to pass the initialization arguments. This need for initialization makes the two classes: caller and callee dependent on each other i.e. they are tightly coupled. Thus, any change in initialization process of callee warrants a change in the code of the caller. Dependency injection removes this need.

  1. The above problem is also addressed using factories where the initialization is moved to a third class which when requested for a callee object, initializes and returns it. This separates the initialization from the logic of the callee but keeps the problem as is. Now the factory code needs to be changed if callee is changed.

  1. Factories are also used to support strategy pattern where the logic is interface driven and implementations are driven by the environment, user choice or even discovery of new algorithms. In such cases, to provide different implementations to the user, not only these new implementations need to be provided but also Factories need to be made aware of the new implementations and hence, need to be recompiled

Dependency Injection approaches and their differences


XML based (Spring)
Annotation based (Guice and Spring annotation based configuration)
Understanding object graphs requires reading fully qualified class names which cannot be browsed by IDE features
Understanding object graphs is simpler as it is not dependent on Strings. The dependencies are declared in a Java file
No compile time help for mismatched dependency i.e. type safety is not enforced
Compile time help for mismatched dependency is available and the type safety is enforced
Dependencies becomes more like configuration

Dependencies are still code. Just as Factories need strings to match references to implementations, annotation based DI need ‘reference types’ (mostly their class objects) to be bound to their implementations

Dependencies can be changed without compilation
Dependencies cannot be changed without compilation
Different instances can have different implementations






Different instances cannot have different implementations if class type is associated as described above. To achieve this, named configurations need to be used for different instances which do not allow compile time checks
Third party libraries can both be injected into the project and the project can also inject dependencies in them
Third party libraries cannot be supported out of the box.


Conclusion

It can be summed up from the discussion above that those software which require being highly configurable, or support multiple implementations of an interface, or support various environments, or support plug and play architecture would do better to stay away from annotation based DI.

Annotation based DI is good for projects which support compilations between various deployments e.g. IT projects servicing single client. Since Annotation based DI provide compile time type safety, it can substantially reduce the development effort.

References

  1. Example of 3rd party DI for Guice: http://code.google.com/p/google-guice/wiki/CustomInjections
  2. A very succinct and to the point Guice tutorial: http://www.factorypattern.com/google-guice-tutorial/
  3. High level Guice vs Spring comparison with a bias towards annotation based DI provider Guice: http://www.theserverside.com/feature/Spring-vs-Guice-The-Clash-of-the-IOC-Containers
  4. Spring vs Guice comparison of each other’s annotation based DI  capabilities: http://www.theserverside.com/feature/Comparing-Spring-vs-Google-Guice-By-Example
  5. Spring vs Guice with a bias towards XML based DI provider Spring http://www.javalobby.org/java/forums/t103070.html
  6. Example of 3rd party DI for spring: http://stackoverflow.com/questions/1509757/injecting-log4j-loggers-with-spring
  7. Guice tutorial: http://code.google.com/p/google-guice/wiki/GettingStarted
  8. Spring reference: http://static.springsource.org/spring/docs/3.0.x/spring-framework-reference/html/