Coding Guru

Code never does the mistake, we make the mistakes in the code. Think, Imagine, Phrase and then Code.

Dependency Injection

The main goal of Dependency Injection is to remove the dependencies of an application. This makes the system more decoupled and maintainable.

Problem that DI solves:

To understand the problem, we need to know two more things.

  1. Dependency Inversion Principle
  2. Inversion Of Control (IOC)

Dependency Inversion Principle:

  1. High-level modules should not depend on low-level modules. Both should depend on abstractions.
  2. Abstractions should not depend upon details. Details should depend upon abstractions.

Example : Suppose  there is a logger  class to log the events of an application . As shown below

class LogEvent{

public void Write(string message) {

//Write to event log here

}

}

class Program{

LogEvent writer = null;

public void Notify(string message){

if (writer == null){

writer = new LogEvent();

}

writer.Write(message);

}

}

See the example carefully, it violate the dependency inversion principle. Because the program class is directly depends upon the concrete class that is LogEvent. With the help of inversion of control this problem can be solve.

Inversion of Control Principal:

1. The higher level modules will depend on abstractions rather than concrete implementation of the lower level modules.

To solve the above scenario, it’s important to create an abstraction and the higher modules should depend upon abstraction instead of concrete class. To create an abstraction an interface is implemented.

  1. //Interface implementation
  2. public interface INofificationAction{
  3. public void ActOnNotification(string message);
  4. }

 

  1. class Program{
  2. INofificationAction action = null; 
  3. public void Notify(string message){
  4. if (action == null){
  5. // Here we will map the abstraction i.e. interface to concrete class
  6. }
  7. action.ActOnNotification(message);
  8. }
  9. }
  1. class LogEvent: INofificationAction{  
  2. public void ActOnNotification(string message){
  3. // Write to event log here
  4. }
  5. }

This solve the problem of dependency inversion principle. But there is something missing.

Example : Suppose  an email sending and  message sending functionality is added to this class.

class EmailSender : INofificationAction{

public void ActOnNotification(string message){

// Send email from here

}

}

class MessageSender : INofificationAction{

public void ActOnNotification(string message){

// Send Message from here

}

}

In this scenario, The interface is depend upon the concrete classes.In the program.class ,The interface must specify the name of concrete class which would  be call .This problem can be solve with the help of Dependency Injection.

Dependency Injection: DI remove all the dependency of an application .With the help of DI the interface dependency will be remove from the concrete classes. The DI can be implemented by different pattern as below.

Dependency Pattern

  1. Constructor injection
  2. Method injection
  3. Property injection

Constructor injection: In this approach an object of the concrete class is pass to the constructor of the dependent class. In this the object of concrete class is initialize on the execution of the program class. It used very commonly in the dependency injection

  1. class Program{
  2. INofificationAction action = null;
  3. public Program(INofificationAction concreteImplementation){
  4. this.action = concreteImplementation;
  5. }
  6. public void Notify(string message){  
  7. action.ActOnNotification(message);
  8. }
  9. }

Method Injection: In this approach an object of concrete class pass to the method of the dependent class which is actually invoking the action.

  1. class Program{
  2. INofificationAction action = null;
  3. public void Notify(INofificationAction concreteAction, string message){
  4. this.action = concreteAction;
  5. action.ActOnNotification(message);
  6. }
  7. }

Property Injection: In this approach an object of concrete class is pass via a setter property and that property will expose by the dependent class. This approach is used less frequently.

  1. class Program{
  2. INofificationAction action = null;
  3. public INofificationAction Action{
  4. get{
  5. return action;
  6. }
  7. set{
  8. action = value;
  9. }
  10. } 
  11. public void Notify(string message){  
  12. action.ActOnNotification(message);
  13. }
  14. }

DI/IOC Container: If the chained and nested dependencies implemented then the dependency injection become very complicated.
So, DI container are used to make it less  complicated. Their are number of IOC container available in the market to make dependency injection easy.Some of them  are:

•    Structure Map
•    Unity
•    Castle Winsdor
•    Ninject

Loading