Click here to Skip to main content
65,938 articles
CodeProject is changing. Read more.
Articles / All-Topics

Dependency Injection in .NET

4.92/5 (12 votes)
5 Jan 2015CPOL5 min read 44.3K  
Dependency Injection in .NET

The post Dependency Injection in .NET appeared first on codecompiled.

In the software development world of today, the emphasis is on applying good design principles and patterns. Applying software principles while developing an application results in less overhead in the long term. After all, the maintenance phase is one of the most expensive phases in the software life-cycle.

One of the things to keep in mind while developing any application today is to create a loosely coupled application design. Creating loosely coupled applications results in applications which are easier to maintain and extend. The requirement changes are frequent today than ever before and so creating an application which is easier to extend is more important today.

Inversion of Control (IoC) is a principle which helps in creating loosely coupled applications. It is just a principle and does not specify the implementation.

In inversion of control, the application flow is inverted. Normally, we call the framework API for different tasks. But in Inversion of control, the framework knows about the objects being used in our application and calls them when required. This call or invocation happens at run time which results in loose coupling between the objects.

IoC says that a component should not depend directly upon any another component, it should rather depend upon an abstraction.

In our application, if we have two classes which depend upon each other, then we may design them as depicted in the below diagram:

dependecy injection

So if we redesign the application according to the IoC principle, then our design can be depicted by the following diagram:

Dependency injection

So Class A now depends upon an abstraction such as an interface or an abstract class.

Some of the examples of design patterns which implement IoC are listed below:

  • dependency injection
  • event loops
  • service locator
  • callbacks

Let's see what is dependency injection and how we can implement it.

In any application, different components or classes work together to achieve a common functionality. We will take the example of Student Information System. We have a class called Student which provides a feature to mail the student details. For sending the mails, the Student class relies on another class called EmailProviderA (EmailProviderA is just another email provider) which provides the mail functionality. As segregating the application functionality into different components is a good practice, so using a separate class for sending a mail is the correct design. Currently, the class is defined as:

C#
class Student
{
private EmailProviderA _emailProviderA ;

public Student()
{
_emailProviderA =new EmailProviderA();
_emailProviderA.Subject = this.Name;
}

public void SendMail()
{
 _emailProviderA.SendMail();
}
} 

As you can see above, the Student class is creating an object of EmailProviderA in its constructor. This may appear to be perfect today but unfortunately it can create problems. Tomorrow, if we want to send mails using any other EmailProvider then we will have to create an object of different class (instead of EmailProviderA) in the constructor of Student class and therefore would need to change our code accordingly.

We can resolve this problem using dependency injection which is an implementation of Inversion of Control principle. According to Dependency injection, the dependency of a class should be injected or passed by the calling code and the class should not be dependent upon the implementation but on an abstraction. So analyzing our Student class in terms of dependency injection, we find the following:

  1. Our class should not depend upon implementation but on an abstraction.
    Student class violates this as it depends upon the EmailProviderA concrete class.
  2. The specific implementation details of the abstraction should not be decided by the class but by the client code or the consumer of the class.
    Student class violates this as it itself creates an instance of the EmailProviderA class.

Let's see how we can modify the class so that it implements dependency injection.

We introduce IEmailProvider interface and make our EmailProviderA class implement this interface. We change the type of reference field in the Student class from EmailProviderA class to the IEmailProvider interface.

C#
interface IEmailProvider
{
bool SendMail();
string Subject{get;set;}
}

class Student
{
private IEmailProvider _emailProvider ;
public Student()
{
_emailProvider=new EmailProviderA();
_emailProvider.Subject = this.Name;
}
public void SendMail()
{
_emailProvider.SendMail();
}
}

Though we have changed the type of the field to interface, but still in our constructor the object of concrete class is being created. So we will remove the code to create the EmailProviderA class from the constructor. In the following code, we have removed the code to create an object of EmailProviderA from the constructor and are passing the interface reference as a constructor argument.

C#
class Student
{
private IEmailProvider _emailProvider ;

public Student(IEmailProvider emailProvider)
{
_emailProvider= emailProvider;
_emailProvider.Subject = this.Name;
}

public void SendMail()
{
 _emailProvider.SendMail();
}

As we need a reference to EmailProviderA class on which our Student class depends so we are passing this as a constructor argument. The client code is responsible for supplying the EmailProviderA reference as a constructor argument, the Student class has no dependency on the EmailProviderA class now.

One obvious advantage of this is if we can easily swap the EmailProviderA class with any other class in our application. The only requirement is that the new class should implement the IEmailProvider interface. We just need to pass the reference to this new class in the Student class constructor. The Student class will remain unchanged.

What we have implemented above is an example of constructor injection. Dependency injection can be implemented using two approaches:

  • Constructor injection: Dependencies are passed through class constructor
  • Property injection: Dependencies are passed through properties

We should use constructor injection when we have required dependencies. Let’s say we have a class which updates some records in the database and needs a connection object to perform this. So we should inject the dependency using constructor here. So when an object of a class could not be created without passing the dependencies, in this case connection object, constructor injection should be used.

On the other hand, property injection should be used if we have many optional dependencies.

We have just seen how to implement constructor injection. To implement the property injection, we just need to add a property which returns an abstraction, an interface, and we can set the value of the property in the calling code. So taking the same example of the Student class, we can introduce a new property as:

C#
public IEmailProvider EmailProviderA
{
set
{
this._emailProvider = value;
}
}

Instead of creating the dependencies ourselves, we can use IoC containers which automatically inject the dependencies.We need to register our dependencies with the container and it is automatically resolved. Some of the common IoC containers which we can use to inject dependencies in .NET are given below:

  • Castle Windsor
  • StructureMap
  • Unity
  • Ninject

Implementing Dependency injection in .NET application has the following advantages:

  • Loose coupling between the application components makes the application more maintainable and extensible
  • Components are easy to unit test
  • Components can be reused

The post Dependency Injection in .NET appeared first on codecompiled.

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)