Sunday, August 1, 2010

Dependency Injection

RAVAGE

After several years of familiarization of the concepts of Dependency Injection (DI) and Inversion of control (IOC), I just came to know about the existence of those concepts. Thanks to Silverlight, PRISM (CAL) and MEF which made me explore the concepts DI and IOC.

Anybody who wants to write an article or explore in depth about Dependency Injection  will never fail to read Martin Fowler's article Inversion of Control Containers and the Dependency Injection pattern, for which I'm no exception.

Inversion Of Control

To understand from the name, its inverting the control of creation. Let's take the case of using the framework in an application, the framework takes the responsibility of creating objects/elements and the application will be hooked up with the created object as and when needed. Fowler states this with the example of UI framework and the application/program where the UI framework holds the responsibility of creating the graphical elements and the application instead creates the event handlers for those fields/graphical elements.

Dependency Injection

Think of a scenario class A uses class B which means class A depends on class B. In order to make use of class B in class A,  usually what we do is we'll write code to instantiate class B in class A. While instantiating class B, we need to pass the values that class B expects, to be clear, we need to satisfy the dependencies of class B. Say if class B expects and depends on class C, then in class A we need to instantiate class C first and then pass it to class B. Also we need to make sure that we should satisfy the dependencies of class C if any.

Ok, now think of changing the instantiating structure of the dependency object. For that we need to change the code in all the areas where it got used. In our example if class c changes its expectation(expects different parameter), we need to change the source code in class A.

There are situations that we don't know the concrete implementation at the time of writing the code or during compile time for various reasons - like we may need the code developed to be reused and the concrete implementation will be known sometime later.

In the above mentioned cases/paragraphs, just the scenarios are mentioned and the intentions are incomplete. Are there any solution for this? If so what is it? How to handle this? Dependency Injection is one solution to handle that.

Dependency Injection Types

  • Constructor injection
  • Setter injection
  • Interface injection
Constructor injection and setter injection are commonly used injection techniques.

As you guess for constructor injection, we need to specify the dependencies as the parameter for the constructor of the class which requires it. Since we're trying to get rid of the concrete implementation, we need to specify the type (interface) of the dependency which it confirms to.

For setter injection, dependencies are exposed as properties which will be set during the instantiation process.

Ok, who'll hold the responsibility of creating, managing and injecting these dependencies? Builder object or containers will do that for you.

Containers

Containers - Are these containers new to .Net based applications? As quoted in msdn CLR itself is a container. If you think it is more generic, let's take the case of asp.net web applications, where there are times that we've used a common base class for handling security, authentication, common functionalities, etc. These base classes can also be considered as a form of container.

Since the containers will create, manage and inject objects, it avoids tight coupling of objects with its dependencies. Containers acts as a repository or lookup manager that maintains instances. We need to map or configure the containers which instances need to be used on which context. Containers also takes additional responsibilities like managing the lifetime of the objects, so that it supplies singleton or new instances upon requests.

Microsoft patterns and practices provides a lightweight extensible container called Unity Application Block. Prism which is used to create modular WPF or Silverlight applications usually uses this Unity Application Block as container.

SUMMARY

Basically Dependency Injection containers decouples the classes from its dependencies and also the responsibility of managing the dependencies. The issues that we face with DI is it's hard to track while debugging. Also we need to make sure that the container has the ability to resolve the dependency where its required. Previously I've specified in this article that dependency injection is one solution. Other solution generally proposed for this scenario is Service Locator.

REFERENCE

http://martinfowler.com/articles/injection.html
http://msdn.microsoft.com/en-us/library/ff649378.aspx
http://msdn.microsoft.com/en-us/library/aa973811.aspx
http://msdn.microsoft.com/en-us/magazine/cc163739.aspx
http://tutorials.jenkov.com/dependency-injection/when-to-use-dependency-injection.html
Creative Commons License
This work by Tito is licensed under a Creative Commons Attribution 3.0 Unported License.