Simple learning. NET CORE MVC Dependency Injection

1, Concept
It is dependency injection that is new to. NET CORE MVC and not used to but very important. Compared with. Net MVC,. NET CORE MVC tends to rely on dependency injection to handle the transfer (Reference) of objects. In the past, it was used to using static objects or instantiated classes. In. NET CORE MVC, it is generally changed to explicitly request dependencies from constructors.

It can be said that dependency injection is the core of. NET CORE MVC, which aims to reduce the coupling between different objects, greatly improve the testability of the system, and make the application easier to test and maintain.

For better decoupling,. NET CORE MVC uses interfaces instead of directly calling concrete object entities. For example:
In the past, it was OK to use MemoryCache.Default directly. However, to use MemoryCache in. NET CORE MVC Controller, first register the service in StartUp, then obtain the instance in the constructor of the Controller, and then use it in the method of the Controller.
Another: we often come into contact with the concept of inversion of control (IOC), but it can be described from different angles of the same concept as dependency injection.

2, NET CORE MVC dependency injection lifecycle
The life cycle here refers to whether to create a new component each time or share an Instance from beginning to end when obtaining a component through dependency.
There are three types:
1.Singleton (single case)
The whole process only creates one Instance and shares it at any time.
2. Scoped
In the web page, a Request process (refers to the execution period from receiving the browser Request to returning the result) shares one Instance.
3. Transient
Each time a component is requested, a new one is created and never shared.

Note: components registered in the DI container also depend on each other. One principle is that components with a long life cycle cannot refer to components with a shorter life cycle. For example, components registered as Singleton cannot rely on components registered as Scoped. The reason is obvious. If the life cycle is shorter than their own, the dependent components may have been reduced and cannot be used in the later stage.
Generally speaking, services that need to be shared by the whole Process can be registered as Singleton. EF Context (reminder: do not share across processes) recommends that they be registered as Scoped to facilitate the reuse of DB connections. If you want to secure points, you can register as Transient.

3, Using dependency injection in. NET CORE MVC
A simple example: display different current time formats

public interface IDateTime
{
    DateTime Now { get; }
}
Public class DateTimeFormat1:IDateTime
{
   Public DateTime Now
{
 Return DateTime.Now.Tostring("yyyy-MM-dd");
}
}

Public class DateTimeFormat2:IDateTime
{
  Public DateTime Now
 {
       Return DateTime.Now.Tostring("MM/dd/yyyy");
 }
}

1. Traditional calling method

Public class MyController:Controller
{
  Private IdateTime dateTime = New DateTimeFormat1();
  Public IActionResult GetDateTime()
 {
    Rerturn Content(dateTime.Now);
 }
}

The above traditional mode directly a NEW instance object (which is also the most frequently used method by many beginners or veterans). If you want to change the referenced object later, such as changing the date format from DateTimeFormat1 "-" to DateTimeFormat2 "/ /", you need to change it in all places in the whole system where the NEW object is used, and the code coupling is too high, Very detrimental to maintenance.

2. Use dependency injection
1) Set injection in the ConfigureServices method of the Startup class

public void ConfigureServices(IServiceCollection services)
{ 
    services.AddTransient<IDateTime, DateTimeFormat1>(); 
....
}

2) In Controller

public class MyController:Controller
{
    private readonly IdateTime _dateTime; 
    public MyController (IDateTime dateTime) //Get instance in constructor
    {
        _dateTime= dateTime;
    }
    [HttpGet]
   Public IActionResult GetDateTime()
 {
    Rerturn Content(_dateTime.Now);
 }
}

When using the dependency injector, the problem of high coupling in the traditional way is solved. If the implementation is changed in the later stage, just add the dependency injector in startup.cs

 services.AddTransient<IdateTime, DateTimeFormat1>();
 Change into
 services.AddTransient<IdateTime, DateTimeFormat2>()
 OK;

There is no need to make any changes in all places where IdateTime is used; You can also easily set the lifecycle (Transient, Scoped, Singleton);

The above MVC Controller dependency injection method is through constructor parameters, which is a typical method.

In addition, we can also have other ways:
Type 1: Action plus [FromServices] Attribute is directly injected into the controller method without constructor injection.

public IActionResult About([FromServices] IDateTime dateTime)
{
    return Content( $"Current server time: {dateTime.Now}");
}

Type 2: you can get the injection directly in the View

For example:@inject IDateTime dateTime
<ul> <li>Now: @dateTime.Now</li> </ul>

Type 3: get injection directly in httpcontext

HttpContext.RequestServices.GetService<IDateTime >();

Note: HttpContext.Current is not available in ASP.NET Core. If you want to use HttpContext outside Controller/View, you need to use IHttpContextAccessor.
For example:

public class DataService : IDataService
{
    private readonly HttpContext _httpContext;

    public DataService(IHttpContextAccessor contextAccessor)
    {
        _httpContext = contextAccessor.HttpContext;
    }
    //...
}

Tags: .NET mvc

Posted on Sat, 02 Oct 2021 16:40:32 -0400 by vmarellano