Use of asp.net core middleware (II): use of dependency injection

Time:2021-10-26

Write in front

In the last article, you have learned about the use of. Net core middleware:Use of ASP. Net core middleware (I): building a static file server / accessing specified files

Many core objects in the. Net core framework are provided through dependency injection. What is dependency injection?

This is also an old question. What is dependency injection? Why use it? Beginners are particularly easy to get confused about concepts such as inversion of control (IOC) and di.


 

What is dependency injection?

When it comes to dependency injection, you must think of control inversion. How can you understand that control inversion is a design principle (inversion of control, abbreviated as IOC), and dependency injection (DI) is its implementation.

Dependencies arise when one class needs the cooperation of another class to complete the work. For example, we need to complete registration and login related to users in the accountcontroller.

Here is a design principle: it depends on abstraction rather than concrete implementation. When a class depends on concrete dependency, it is considered to be related to the classTight coupling

 

What is the purpose of dependency injection?

Control inversion is used to decouple and reduce the coupling between interface and implementation. One advantage is that an interface can be implemented differently, so as to improve scalability and ensure code maintainability and scalability.

In popular terms,Before the object is used, we need to create a new object, create an instance object, and then perform other operations.

 

How to use dependency injection?

The. Net core comes with a dependency injection framework. We can summarize these usage methods. Of course, there are many usage methods (general, generic and factory). I won’t give an example one by one:

  • Constructor injection;

  • Method injection;

  • Attribute injection;

Isn’t it hard to understand such a summary? It doesn’t matter. We further refine the usage as follows:

  1. Inject in the constructor of startup type;

  2. Inject in the configure method of startup type;

  3. Inject in the middleware type constructor;

  4. Inject in the invoke / invokeasync method of middleware type;

  5. Inject in the constructor of controller type;

  6. Inject in the action method of the controller;

 


 

1、 Inject in the constructor of startup type

The configured iconfiguration object and the ihostenvironment object representing the hosting environment can be directly injected into the startup constructor.

Of course, information related to the current hosting environment can also be obtained by injecting iwebhostenvironment objects,

This is because the hosting environment in the asp.net core application is represented by the iwebhostenvironment interface, which is derived from the ihostenvironment interface).

 

We can verify the constructor injection for startup through a simple example.

As shown in the following code snippet, we are calling startup of the iwebhostbuilder interfaceMethod registered a custom startup type.

When defining the startup type, we inject the above three objects into its constructor. The provided debugging assertion not only proves that the three objects are not null, but also shows that the same instance is obtained by using ihostenvironment interface and iwebhostenvironment interface.

 

class Program
{
    static void Main()
    {
        Host.CreateDefaultBuilder().ConfigureWebHostDefaults(builder => builder.UseStartup())
        .Build()
        .Run();
    }
}

public class Startup
{
    public Startup(IConfiguration configuration, IHostEnvironment hostingEnvironment,IWebHostEnvironment webHostEnvironment)
    {
        Debug.Assert(configuration != null);
        Debug.Assert(hostingEnvironment != null);
        Debug.Assert(webHostEnvironment != null);
        Debug.Assert(ReferenceEquals(hostingEnvironment, webHostEnvironment));
    }
    public void Configure(IApplicationBuilder app) { }
}

 


 

2、 Inject in the configure method of startup type

 

This injection method is also called pipeline injection, which is a more commonly used injection method, because the framework (pipeline injection) has been generated in the startup.cs class when the. Net core creates the project,

If constructor injection can also select the injected services, then for the configure method, any service registered in any way can inject itsIncluding by calling

The services registered by ihostbuilder, iwebhostbuilder and startup’s own configureservices method also include all services registered by the framework itself.

As shown in the following code snippet, we call the configureservices methods of iwebhostbuilder and startup respectively to register the services for the IStudent interface and iSchool interface, which are directly injected into the configure method of startup. In addition, the configure method needs toIt is required to provide an iaapplicationbuilder object used to register middleware as a parameter, but there are no restrictions on the location of the parameter.

class Program
{
    static void Main()
    {
        Host.CreateDefaultBuilder().ConfigureWebHostDefaults(builder => builder
            .UseStartup()
            .ConfigureServices(svcs => svcs.AddSingleton()))
        .Build()
        .Run();
    }
}

public class Startup
{
    public void ConfigureServices(IServiceCollection services) => services.AddSingleton();
    public void Configure(IApplicationBuilder app, IStudent student, ISchool school)
    {
        Debug.Assert(student != null);
        Debug.Assert(school!= null);
    }
}

 


 

3、 Inject in middleware type constructor

 

The most important object of asp.net core request processing pipeline is the middleware used to really process requests.

Because when asp.net core creates middleware objects and uses them to build the entire request processing pipeline,All services have been registered, so any registered service can be injected into the constructor of middleware type.

The code snippet shown below reflects the constructor injection for middleware types.

class Program
{
    static void Main()
    {
        Host.CreateDefaultBuilder().ConfigureWebHostDefaults(builder => builder
            .ConfigureServices(svcs => svcs
                .AddSingleton()
                .AddSingleton()
                .AddSingleton())
            .Configure(app => app.UseMiddleware()))
        .Build()
        .Run();
    }
}

public class studentschoolMiddleware : IMiddleware
{
    public studentschoolMiddleware(IStudent student, ISchool school)
    {
        Debug.Assert(student != null);
        Debug.Assert(school != null);
    }

    public Task InvokeAsync(HttpContext context, RequestDelegate next)
    {
        Debug.Assert(next != null);
        return Task.CompletedTask;
    }
}

 


4、 Inject in the invoke / invokeasync method of middleware type

If the contract based Middleware type definition method is adopted, the registered service can also be directly injected into the invokeasync method or invoke method that is really used to process requests.

In addition, naming the method invokeasync is more in line with the tap (Task-Based asynchronous pattern) programming mode. The reason why the invoke method name is retained is mainly for the purpose of version compatibility.

The code snippet shown below shows the service injection for the invokeasync method.

class Program
{
    static void Main()
    {
        Host.CreateDefaultBuilder().ConfigureWebHostDefaults(builder => builder
            .ConfigureServices(svcs => svcs
                .AddSingleton()
                .AddSingleton())
            .Configure(app => app.UseMiddleware()))
        .Build()
        .Run();
    }
}

public class studentschoolMiddleware
{
    private readonly RequestDelegate _next;

    public studentschoolMiddleware(RequestDelegate next) => _next = next;
    public Task InvokeAsync(HttpContext context, IStudent student, ISchool school)
    {
        Debug.Assert(context != null);
        Debug.Assert(student != null);
        Debug.Assert(school != null);
        return _next(context);
    }
}

For contract based Middleware, there is an essential difference between constructor injection and method injection.

Since middleware is registered as a singleton object, we should not inject scoped services into its constructor.

The scoped service can only be injected into the invokeasync method of middleware type. Because the dependent service is provided in the service scope for the current request, it can ensure that the scoped service is released after the processing of the current request is completed.


5、 Inject in the constructor of controller type

In an asp.net core MVC application, we can inject the required services by constructor injection in the defined controller.

In the code snippet shown below, we inject the istudentschool service into the constructor of the homecontroller.

class Program
{
    static void Main()
    {
        Host.CreateDefaultBuilder().ConfigureWebHostDefaults(builder => builder
            .ConfigureServices(svcs => svcs
                .AddSingleton()
                .AddSingleton()
                .AddControllersWithViews())
            .Configure(app => app
                .UseRouting()
                .UseEndpoints(endpoints => endpoints.MapControllers())))
        .Build()
        .Run();
    }
}

public class HomeController : Controller
{
    public HomeController(IStudentschool studentschool) => Debug.Assert(studentschool!= null);

}

 


6、 Inject in the action method of the controller

With the help of the parameter binding mechanism based on model binding of asp.net core MVC,We can bind the registered service to the parameters of the target action method, and then implement dependency injection for the action method.

stayWhen using this type of injection method, we need to mark the fromservicesattribute attribute on the injection parameters in the following way to determine that the source of parameter binding is the registered service.

In the code snippet shown below

class Program
{
    static void Main()
    {
        Host.CreateDefaultBuilder().ConfigureWebHostDefaults(builder => builder
            .ConfigureServices(svcs => svcs
                .AddSingleton()
                .AddControllersWithViews())
            .Configure(app => app
                .UseRouting()
                .UseEndpoints(endpoints => endpoints.MapControllers())))
        .Build()
        .Run();
    }
}

public class HomeController: Controller
{
    [HttpGet("/")]
    public void Index([FromServices]IStudentschool studentschool)
    {
        Debug.Assert(Studentschool!= null);
    }
}

 


7、 Inject in view

In the asp.net core MVC application, we can also register the service in the current view.

Suppose we define the following simple MVC program and a simple homecontroller.

The following code snippet

class Program
{
    static void Main()
    {
        Host.CreateDefaultBuilder().ConfigureWebHostDefaults(builder => builder
            .ConfigureServices(svcs => svcs
                .AddSingleton()
                .AddControllersWithViews())
            .Configure(app => app
                .UseRouting()
                .UseEndpoints(endpoints => endpoints.MapControllers())))
        .Build()
        .Run();
    }
}

public class HomeController: Controller
{
        [HttpGet("/")]
        public IActionResult Index() => View();
}

We have defined an action index method for homecontroller that routes to the root path (“/”). Before calling the view method to render the default view,

Pass the injected istudentschool service to the view in the form of viewbag.

The code snippet shown below is the definition of the view (/ views / home / index. Cshtml) corresponding to the action method. We injected the istudentschool service through the @ inject instruction, and

Set the property name to studentschool, which means that the current view object will add a studentschool property to reference the injected service.

@inject IStudentschool Studentschool
@
{
    Debug.Assert(Studentschool!= null);
}

 


Write it at the back

Here is a brief introduction to the use of. Net core dependency injection. More use methods need to be explored, and some precautions in the use process also need to be explored, such as:

  • Effectively design services and their dependencies;
  • Prevent multithreading problems;
  • Prevent memory leakage;
  • Prevent potential errors;
  • If service injection is used, the service life cycle should also be considered (a service cannot rely on a service whose life cycle is less than its own.);

 

reference resources: https://www.cnblogs.com/artech/p/di-in-asp-net-core-3.html

 

Welcome to subscribe to my wechat public platform [Xiong Ze has something to say], more fun and easy to learn knowledge are waiting for you

Author: Xiong Ze – pain and joy in learning

Official account: Bear’s saying

source: https://www.cnblogs.com/xiongze520/p/14155858.html


The creation is not easy. The copyright belongs to the author and the blog park. For reprint or partial reprint and excerpt, please indicate the author and the original link in the obvious position of the article.