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


Related articles: