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:
So if we redesign the application according to the IoC principle, then our design can be depicted by the following diagram:
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:
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:
- Our class should not depend upon implementation but on an abstraction.
Student
class violates this as it depends upon the EmailProviderA
concrete class. - 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.
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.
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:
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.