Understanding Dependency Injection with C#
An easy guide to learn fundamentals of dependency injection
Dependency Injection or DI is a design pattern that allows to delegate the creation of dependent objects to another entity outside the main class. DI allows programs to have loosely coupled classes. Let’s understand this with simple examples.
The following example shows a simple class BusinessLogicLayer,
it provides the necessary operations to get information from database. It creates an object of DataAccessLayer
to access to these operations.
In this above example, BusinessLogicLayer
class depends on DataAccessLayer
class. There are some problems with this approach, classes are tightly coupled : BusinessLogicLayer
class needs to create a concrete object of DataAccessLayer
and manages its lifetime, all changes in DataAccessLayer
can have an impact on BusinessLogicLayer
class, finally BusinessLogicLayer
class can’t be tested independently of DataAccessLayer
class.
To avoid these problems we can use DI pattern.
Dependency Injection Implementation
As I said before, DI is a way to delegate lifetime of dependent objects to another component and inject those objects inside the class that depends on them. There are three ways to inject dependencies :
Constructor Injection
In the constructor injection, the injector (delegated class) creates new instances of dependent objects through its constructor.
In this above example, BusinessLogicLayer
class has a constructor with an abstract type IDataAccess
implemented by DataAccessLayer.
The delegated class InjectorService
creates a concrete object and injects this object into BusinessLogicLayer
.
Property Injection
In the property injection, the injector (delegated class) injects dependent objects through a public property.
In this above example, BusinessLogicLayer
class has a public property of an abstract type IDataAccess
implemented by DataAccessLayer.
The delegated class InjectorService
creates a concrete object and sets the public property.
Method Injection
In the method injection, the injector (delegated class) uses a specific method to inject dependent objects.
In this above example, BusinessLogicLayer
class has a specific method called IDataAccessDependency.SetDependency().
The delegated class InjectorService
uses this method to inject DataAccessLayer
class dependency.
In real world, there are many delegated containers that help us to implement Dependency Injection, Unity Container is one of the most famous in the Microsoft Community.
Using Unity Container
The Unity container (Unity) is an open source package that facilitates building loosely coupled applications. To install Unity you can use NuGet package.
Let’s take the same example from the previous chapter. In the previous sections, we used a customize class named InjectorService
to inject dependencies, now we are going to use Unity instead of creating a customize class.
As you can see in this above example. We created an instance of Unity Container, next we register the type-mapping with the container like this container.RegisterType<IDataAccess, DataAccessLayer>().
This instruction creates an instance of DataAccessLayer
class. After that, we use container.Resolve<BusinessLogicLayer>()
method to create an object of BusinessLogicLayer.
Finally, the created object is used to get needed data.
As you can see, the Unity Container is easy to use, it exposes the following operations :
- RegisterType : to instantiate all dependencies.
- Resolve : to create an object by injecting registered dependencies.
For more details, visit the Unity website here.
Thanks for reading. I hope this article was helpful.
The source code is available on GitHub: