During
software development, we usually find different parts of our application are unnecessarily depended on each other. This reduces
the flexibility of code and may cause issues. So we want the components of
our application to be as independent as possible.
Here
is a simple example to describe how we can de-couple objects.For example, we need to build an application about a man
drives car, truck, and tractor.We have a man class like this:
public
class Man
{
private
Car car = new Car();
private
Truck truck = new Truck();
private
Tractor tractor = new Tractor();
public Man() {}
public
void driveCar()
{
car.drive();
}
public
void driveTruck();
{
truck.drive();
}
public
void driveTractor();
{
tractor.drive();
}
}
As
you can see, the "Man" class is coupled with 3 other classes. Any
change on those classes (for example, Truck class is renamed
to BigTruck) may cause Man class stop working or can not be compiled.
It's
time to de-couple them. We define an interface named IVehicle:
public
interface IVehicle
{
void
drive();
}
We
re-define Car, Truck, and Tractor class to implement this interface:
public
class Car : IVehicle
{
public void drive() { Console.WriteLine("drive car.");}
}
public
class Truck : IVehicle
{
public void drive() {Console.WriteLine("drive truck.");}
}
public
class Tractor : IVehicle
{
public void drive() {Console.WriteLine("drive tractor.");}
}
Then
we change Man class as following to de-couple:
public
class Man
{
private IVehicle vehicle;
public Man(IVehicle _vehicle)
{
vehicle = _vehicle;
}
public
void drive()
{
vehicle.drive();
}
}
We
can "inject" the dependency at runtime like this:
IVehicle
vehicle = new Car();
Man
man = new Man(vehicle);
man.drive();
// Man drives the car
vehicle
= new Truck();
man
= new Man(vehicle);
man.drive();
// Man drives the truck
vehicle
= new Tractor();
man
= new Man(vehicle);
man.drive();
// Man drives the tractor
This
is much better than the old code. But it's not enough, because we still have to create dependencies somewhere in
our application. It's the time to introduce Dependency Injection Container, also known
as IoC(Inversion of Control) container. It's an intermediate component to create the
dependencies for us. What we need to do is register the interfaces with the DI container
and tell it which actual class instances should be created to satisfy dependencies. In my next blog, I
will talk about Ninject, a DI container can be added into Visual Studio 2010 project.