Dependency Injection in ASP.NET Core

Introduction 

 
Dependency injection is a software design pattern that enables users to create an application with loosely coupled code. The term 'loosely coupled' means objects that should only have as many dependencies as required to complete their job by decreasing the tight coupling between the software components. Object's dependencies should be on interfaces as opposed to the concrete object. An object is concrete in the sense that it is created with the "new" keyword.
 

Advantages of Dependency Injection

  • Easier Maintainability
  • Greater re-usability
Code is more easily testable with different mock implementation.
 
Code is cleaner and more readable
 
There are basically 3 types of Dependency injection in ASP.NET Core:
  • Constructor Injection
  • Method Injection
  • Property Injection

Constructor Injection

 
Constructor injection is the most common dependency injection used in an application. Constructor injection uses parameters to inject the dependency. It accepts the dependency at the constructor level. It means when instantiating the class, their dependency pass through the constructor of the class.
 
Implementing Constructor Injection
 
In the below code, HomeController has a dependency on IEmployeeRepository. We are not creating an object of EmployeeRepository using the new Keyword but we are injecting IEmployeeRepository in Home Controller class using its constructor. This is called constructor injection.
  1. using DependencyInjectionTech.Models;  
  2. using Microsoft.AspNetCore.Mvc;  
  3. namespace DependencyInjectionTech.Controllers {  
  4.     [Route("api/[controller]")]  
  5.     [ApiController]  
  6.     public class HomeController: ControllerBase {  
  7.         private IEmployeeRepository _employeeRepository;  
  8.         // Constructor Injection  
  9.         public HomeController(IEmployeeRepository employeeRepository) {  
  10.                 _employeeRepository = employeeRepository;  
  11.             }  
  12.             [HttpGet]  
  13.             [Produces("application/json")]  
  14.         public Employee GetEmployee() {  
  15.             return _employeeRepository.GetEmployee(1);  
  16.         }  
  17.     }  
  18. }  
While running the application, we will get the below error because we have to manually register the interface IEmployeeRepository and its implementation class in the Asp.Net Core dependency injection container. Unless we won't do that process, we will get the below error:
 
An unhandled exception occurred while processing the request.
 
InvalidOperationException: Unable to resolve service for type 'DependencyInjectionTech.Models.IEmployeeRepository' while attempting to activate 'DependencyInjectionTech.Controllers.HomeController'.
 
For registering the interface and its implementation, we have a startup class where we configure the service methods. We make use of the ConfigureServices method to configure the required service for our application. We can use this method to configure in both the ASP.NET Framework Service as well as our application-related custom service. We can make use of the incoming parameter type IServiceCollection of the Configure service method to configure the service.
 
There are basically 3 methods to register our custom service in the configure service method:
  • Add Singleton
  • Add Transient
  • Add Scoped
The below code in the startup file indicates if any controller (for example HomeController) requests IEmployeeRepository. Then it will automatically create an instance of MockEmployeeRepository class and then inject the instance.
  1. // This method gets called by the runtime. Use this method to add services to the container.  
  2. public void ConfigureServices(IServiceCollection services) {  
  3.     services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_1);  
  4.     //Registering the interface and its implementation in asp.net core dependency injection container.  
  5.     services.AddSingleton < IEmployeeRepository, MockEmployeeRepository > ();  
  6. }  

Method Injection

 
Method Injection enables you to inject the dependency into a single method to be only used by that method. We make use of the [FromService] attribute for the method Injection.
 
Implementing the Method Injection
 
In the below code, we are implementing the method injection in a single method.
  1. namespace DependencyInjectionTech.Controllers {  
  2.     [Route("api/[controller]")]  
  3.     [ApiController]  
  4.     public class HomeController: ControllerBase {  
  5.         public HomeController() {}  
  6.         //Method Injection  
  7.         [HttpGet]  
  8.         [Produces("application/json")]  
  9.         public Employee GetEmployee([FromServices] IEmployeeRepository _employeeRepository) {  
  10.             return _employeeRepository.GetEmployee(1);  
  11.         }  
  12.     }  
  13. }