Search This Blog

Saturday, January 26, 2008

Dependency Injection Explained.

Dependiency Injection Explained
Let us assume that interface A has a method doAction(). this doAction() requires an instance of a class implementing the interface B. Also let's assume that we have class A1 and A2 which implements A and class B1 and B2 which implements interface B.

In the do() mehod in Class C these classes will be used in this manner.
public void do()
{
A a = new A1();
a.doAction();
}
for this to work A1 should asociate with an instance of B.
typical implementation would be
class A1 implements A{
B b = null;
public A()
{
b = new B1();
}

public void doAction()
{
//uses b
}
}

The problem with this definition of A1 and B1 is that B1 ise intimately coupled in the definition of Class A1. A1 has to no which instance of B is used (ie B1)

One step forward is to have a setB() method in the A interface and let the calling class tell Which implementation of B to be used. This looks more configurable, but effectively we are moving the decision to class C.

Now do() method will change to following
public void do()
{
A a = new A1();
a.setB(new B1());
a.doAction();
}
the difference is instead A1 determining which B to be used now the method do() is determining

With dependency injection this decision is left to the container. Dependency injection supported container before giving the Class A1 to be used by Class C it will set the instance of B1 to b. Now all the instances of the classes As, Bs and Cs are decoupled.

But we need a way to inform the container that when giving an instance of A1 it should set the b to B1 before providing to the application.. This is called wiring and is done by the dependency injection container. In spring this can be specified in XML.

Why use DI
if TDD(Test Driven Development) is used, the advantage gained when creating test cases alone justifies the use of Dependency Injection . If for testing and production different implementations of B is requuired then it can be easily done if DI is used. An instance of a mock object MockB can be used easily if DI prinicpal is used. With the earlier two implementation with the first one it's impossible to use MockB and in the sescond instance MockB can be used to test doAction() method but cannot be used to test do() method.

No comments: