ASP.NET Core 核心组件中间件自定义

ASP.NET Core中间件是一种装配到应用管道以处理请求和响应的软件,中间件是ASP.NET Core 的核心组件。ASP.NET Core 提供了很多丰富的内置中间件组件,但是当内置的中间件不满足需求的情况下,那么你就需要写入自定义中间件。.

初尝试

    怎么实现中间件自定义呢,首先我们看看简单的在应用管道里注册中间件和自定义中间件注册。新建一个控制台程序,增加一个Start方法,如下

       public static void Start()        {         //新建一个hosting服务            var host = Host.CreateDefaultBuilder()            //注册web寄宿服务并默认调用Kestrel服务             .ConfigureWebHostDefaults(builder => builder             .Configure(app =>              app.UseRouting()//注册自带的路由中间件             //模拟一个中间件 在默认页面打印Hello world!              .Run(context => context.Response.WriteAsync("Hello world!"))             )             ).Build();            host.Run();        }

结果为:

ASP.NET Core 核心组件中间件自定义

是我们预期的效果。

注意,在控制台应用开启web服务需要修改项目csproj中的sdk,如下

把<Project Sdk="Microsoft.NET.Sdk">修改为:<Project Sdk="Microsoft.NET.Sdk.web">即可

再深入

    接下来我们模拟asp.net core中间件注入的使用场景,代码如下:

       //这块相当于ASP.NET CORE的program.cs文件       public static void Start()        {            var host = Host.CreateDefaultBuilder()//新建Hosting服务              //创建web服务                .ConfigureWebHostDefaults(builder => builder                   //指定要由 Web 主机使用的启动类型。这里启动类是Startup                    .UseStartup<Startup>())                .Build();
            host.Run();        }        //启动类是Startup,相当于Startup.cs        public class Startup        {    //这里可以进行依赖注入            public void ConfigureServices(IServiceCollection services)            {            }            //这里可以注册原生管道或者自定义管道            public void Configure(IApplicationBuilder app)            {            }        }

使用中间件环境配置好了,自定义中间件可以分为两种类型,一是强类型定义,它的好处是实现了Imiddleware接口,使用相对灵活;另一种是基于约定,这种使用的好处是不需要实现任何接口,而且是单例模式。接下来我们先来自定义一个Imiddleware类型的中间件。

      //需要继承IMiddleware接口,然后实现InvokeAsync方法        public class HelloMiddleware : IMiddleware        {            public async Task InvokeAsync(HttpContext context, RequestDelegate next)            {                await context.Response.WriteAsync("Hello Middleware");            }        } //在我们写好的入口程序使用       public class Startup        {            public void ConfigureServices(IServiceCollection services)            {//单例依赖注入                services.AddSingleton<HelloMiddleware>();            }            public void Configure(IApplicationBuilder app)            {//用UseMiddleware注册HelloMiddleware中间件                app.UseMiddleware<HelloMiddleware>();            }        }

输出结果:Hello Middleware。

下面我们使用基于约定来实现

        //基于约定 先建一个类        public class TestMiddleware        {            //当前中间件需要传递给后续的中间件 我需要调用RequestDelegate _next            private readonly RequestDelegate _next;            public TestMiddleware(RequestDelegate next)            {                _next = next;            }            //自己写一个InvokeAsync方法            public async Task InvokeAsync(HttpContext httpContext)            {                await httpContext.Response.WriteAsync("Holle TestMiddleware");            }        }  //启动类是Startup,相当于Startup.cs          public class Startup        {    //这里可以进行依赖注入 如果中间件里用的其他类,需要在这里依赖注入            public void ConfigureServices(IServiceCollection services)            {            }            //这里可以注册原生管道或者自定义管道            public void Configure(IApplicationBuilder app)            {              //用UseMiddleware注册TestMiddleware中间件               app.UseMiddleware<TestMiddleware>();            }

输出结果:Holle TestMiddleware。达到所需要的效果。

结语

    本文讲了ASP.NET Core 核心组件中间件的两种自定义方式,约定和强类型,并举例如何使用,大家可以把代码拷贝到本机vs尝试一下ASP.NET Core 的奥秘。此案例适用于.NET Core 3.1、.NET5,在.NET6使用方式略有不同,大家可以试一试。写作水平有限,欢迎大家留言讨论。