Three ways to resolve dependencies in ASP. NET Core 6
- 2021-12-04 09:54:05
- OfStack
Dependency injection is a technique that allows us to inject dependent objects of a specific class instead of creating these instances directly.
The benefits of using dependency injection are obvious. It improves the maintainability and testability of the system by loosening the coupling between modules.
Dependency injection allows us to modify concrete implementations without changing the types of dependencies that depend on them.
ASP. NET Core attaches great importance to dependency injection technology. The built-in dependency injection module in ASP. NET Core is not as versatile as the IoC (inversion of control) containers such as StructureMap and Ninject, but it is fast, easy to configure, and easy to use. We can use it to inject framework services and application services into ASP. NET Core.
For knowledge about dependency injection and inversion of control, please refer to: design pattern.
We'll show you three different ways to resolve dependencies in ASP. NET Core 6.
The code examples provided in this article all run on Visual Studio 2022 by default.
1. Create an ASP. NET Core project using VS 2022
We created an ASP. NET Core project in Visual Studio 2022. Follow these steps to create a new ASP. NET Core Web API 6 project in Visual Studio 2022.
1) Start Visual Studio 2022 IDE. 2) Click "Create new project". 3) In the "Create new project" window, select "ASP. NET Core Web API" from the list of templates displayed. 4) Click the next step. 5) In the "Configure your new project" window, specify the name and location of the new project. 6) Select the "Place solution and project in the same directory" check box according to your preference. 7) Click the next step. 8) In the "Additional Information" window that appears next, select. NET 6.0 as the target frame from the top drop-down list. Leave "Authentication Type" as "None" (default). 9) Make sure that the "Enable Docker," "Configure for HTTPS" and "Enable Open API Support" check boxes are not selected, because we will not use any of these features here. You can also choose to uncheck the "Use controllers (uncheck to use minimal API)" check box because we will create our own controllers. 10) Click Create.This will create a new ASP. NET Core 6 Web API project in Visual Studio 2022. We will use this project in later parts of this article to illustrate resolving dependencies.
2. Resolve dependencies using constructor injection
Now create the following interface:
public interface ICustomFileLogger
{
public string Text { get; set; }
public void Log(string message);
}
For simplicity, we give a minimum representation.
CustomFileLogger
Class implementation
ICustomFileLogger
Interface, code as follows:
public class CustomFileLogger : ICustomFileLogger
{
public string Text { get; set; }
public void Log(string message)
{
// Your own implementation logic
}
}
If you are using ASP. NET 5, you can use the
ConfigureServices
Register 1 in the method
ICustomFileLogger
Type as an instance of a
Scoped
Service. If you are using ASP. NET 6, register directly in the Program. cs file.
services.AddScoped < ICustomFileLogger, CustomFileLogger > ();
Next, create a file named
DefaultController
API controller and enter the following code:
[Route("api/[controller]")]
[ApiController]
public class DefaultController : ControllerBase
{
private ICustomFileLogger _logger;
public DefaultController(ICustomFileLogger logger)
{
_logger = logger;
if(string.IsNullOrEmpty(_logger.Text))
_logger.Text = DateTime.UtcNow.ToString();
}
[HttpGet]
public string Get()
{
return "Hello World!";
}
}
Notice how constructor injection is used here.
DefaultController
The constructor of the class accepts
ICustomFileLogger
Type as a parameter.
3. Use action method injection to resolve dependencies
When we need to use injected instances in multiple methods, we should use constructor injection. If you only need to use instances in specific action methods, it is better to inject instances in action methods instead of using constructor injection.
The following code snippet shows how to implement action method injection.
[HttpPost("Log")]
public IActionResult Log([FromServices] ICustomFileLogger customFileLogger)
{
// Your own implementation logic
return Ok();
}
4. Resolve dependencies using IServiceProvider
Sometimes we may need to inject many different services into the controller. If constructor injection is used, multiple parameters must be specified in the constructor. Therefore, in this scenario, there is a better solution, which is to use
IServiceProvider
.
We can use
IServiceCollection
Interface to create a dependency injection container. 1 once the container is created,
IServiceCollection
Instances will be combined into 1
IServiceProvider
Instance. We can use this instance to resolve the service.
We can put
IServiceProvider
Type is injected into any method of the class. You can also take advantage of
IApplicationBuilder
Interface's
ApplicationServices
Attributes and
HttpContext
Class
RequestServices
Property to retrieve the
IServiceProvider
Instance.
The following code shows how to inject
IServiceProvider
An instance of type:
public class DefaultController : Controller
{
private IServiceProvider _provider;
public DefaultController(IServiceProvider provider)
{
_provider = provider;
}
}
We can use the following code in the action method to retrieve any service instance we need.
ICustomFileLogger logger = (ICustomFileLogger)_provider.GetService(typeof(ICustomFileLogger));
Attention
IServiceProvider
Adj.
GetService
Method is used to retrieve service instances.
We can use
HttpContext
Class
RequestServices
Property to retrieve the
IServiceProvider
Type, and then use that instance to call the
GetService
Method.
The following code shows the
HttpContext
Class retrieves instances:
ICustomFileLogger logger = (ICustomFileLogger)HttpContext.RequestServices.GetService(typeof(ICustomFileLogger));
STEP 5 Summarize
Dependency injection is a method to enhance code maintenance and testability by relaxing coupling.
We can use the built-in dependency injection support in ASP. NET Core to create modular, lean, and clean applications while also making them easier to maintain and test.
References:
1. Design patterns
2. C # Tutorial