Dependency injection is a technique for achieving an inversion of control between classes and its dependencies. Now before we go further in this, we first need to know what inversion of control is and before that we also need to know what IOC container is.
IOC container manages object creation and its life cycle. IOC containers manage creations of object and disclose of objects, so we don’t have to manage it explicitly.
Net Core injects objects of dependency classes through constructor or method by using built in IOC container.
Dependency injection in a simplistic way
- DI is an integral part of ASP.Net core
- DI is a form of IOC (Inversion of control)
- DI is the fifth principle of S.O.I.L.D
DI By example
If we need to call any method of the class, then we need to create object of that class and using that object we can call that method. This method will not work for the large-scale project as in the large-scale project if we need to rename class name somehow, then we need to make changes in various places where we have created object of that class.
To fix this, we can user repository design pattern, in the repository design pattern we can define an interface and can implement that interface. You will get more idea about this in the below example.
Below IEmployeeService is created, having one method to get EmployeeName using EmployeeId
Above interface is implemented as per below.
Now, if we need to use above interface in any controller for example EmployeeController than we must inject dependency of IEmployeeService interface in the EmployeeController. We can inject dependency in the constructor using below line of the code.
We have one more issue here as we have shown above to use any service, we first need to register that service in the IOC Container. To register that service we have to add below line of codes in the ConfigureServices of the startup class.
Once we have added above line of code, we can use EmployeeService any controller by just passing IEmployeeService in the constructor of that class.
Now as we have to register service in the configure service class,we have to also define its lifetime, so let us see what are option available for the service lifetime.
We can define service lifetime in below 3 ways.
- Transient Service
- It always creates new instance of the service.
- Where to use: Transient service is safer to use as it always creates new instance. We can use this for a simple and lightweight application.
- Disadvantage: As it always creates new instance it consumes lots of memory.
- Advantage: Require a less maintenance and can use it heavily for smaller and lightweight application.
- Scoped Service
- It creates new instance of the service and shared across all the requests. Once you refresh the page it will create a new instance of the service.
- Where to use: We can use scope service lifetime in an application, where we want different behaviour for each user.
- Advantage: widely used, require less maintenance as instance created for each request, more suitable for an application where we want behaviour to be change on each request.
- Disadvantage: It consume more memory than singleton.
- Singleton Service
- It creates only single instance of the service and shard across all the users. When you restart the application than only it creates new instance of the service.
- Where to use: For a singleton application we can use singleton service.
- Advantage: Very simply and single instance will be created so it requires very less memory.
- Disadvantage: Memory leaks in these services will build up over time.
Ways to use Dependency Injection
- Constructor injection
We can inject service in the constructor as we have shown above in our example. You can inject using below line of code.
- Action injection
Inject service in the constructor have one drawback even if we require to use service in just one function than and if it not called any functionality runtime than also injected service is there which remain useless. To overcome this issue, we can also inject service in the action method of the controller. We can use below line of code for that.
- View injection
We can inject any service in the view as well. For example please check below example to inject configuration service in the view.@using Microsoft.Extensions.Configuration
- Middleware injection
We can inject service in the middleware using constructor injection, below is the sample code for that.
We can see that; we can inject service in the middleware in the same way as we are doing for the constructor. Here we can see that middleware only initialize once when application start so in this case service lifetime will be singleton when we inject it in the middleware.