.NET Core管道模型及中间件应用

官网参考博文

管道模型

ASP.NET管道

当一个http请求被送入到HttpRuntime之后,这个Http请求会继续被送入到一个被称之为HttpApplication Factory的一个容器当中,而这个容器会给出一个HttpApplication实例来处理传递进来的http请求,而后这个Http请求会依次进入到如下几个容器中:HttpModule --> HttpHandler Factory --> HttpHandler。当系统内部的HttpHandler的ProcessRequest方法处理完毕之后,整个Http Request就被处理完成

ASP.NET Core管道

.NET Core管道支持热插拔,用一个个中间件(Middleware)取代ASP.NET的IHttpModule 和IHttpHandler

  • Server将接收到的请求直接向后传递,依次经过每一个中间件进行处理,然后由最后一个中间件处理并生成响应内容后回传,再反向以此经过每个中间件,直到由Server发送出去
  • 中间件就像一层一层的“滤网”,过滤所有的请求和响应
名词浅析

管道:决定如何处理请求,由Startup.cs文件中的Configure()进行配置

// .NET Core3.1默认代码
        // This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
        public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
        {
            if (env.IsDevelopment())
            {
                // 中间件
                app.UseDeveloperExceptionPage();
            }
            app.UseRouting();

            app.UseAuthorization();

            app.UseEndpoints(endpoints =>
            {
                endpoints.MapControllers();
            });
        }

中间件(Middleware):是一个可以处理HTTP请求或响应的软件管道

  • 中间件组件可以处理请求, 并决定不调用管道中的下一个中间件,从而使管道短路
  • 可以同时传入请求和传出响应
  • 中间件组件是按照添加到管道的顺序进行执行的
中间件
注册
  • 终结者模式(Run())
    • Run 终结式只是执行,没有去调用Next ,一般作为终结点。
    • 所谓Run终结式注册,其实只是一个扩展方法,最终还是调用Use方法
  • Use 方法注册
    • use 方式注册中间件得出的结论是:Use注册动作 不是终结点 ,执行next,就可以执行下一个中间件
    • 如果不执行,就等于Run
app.Use(async (context, next) =>
{
    await context.Response.WriteAsync("Hello 1 开始");
    await next();//调用下一个中间件
    await context.Response.WriteAsync("Hello 1 结束");
});
app.Use(async (context, next) =>
{
    await context.Response.WriteAsync("Hello 2 开始");
    await next();
});

Hello 1 开始

Hello 2 开始

public IApplicationBuilder Use(Func<RequestDelegate, RequestDelegate> middleware)
{
     _components.Add(middleware);
     return this;
}

 public RequestDelegate Build()
 {
            RequestDelegate app = context =>
            {
                // If we reach the end of the pipeline, but we have an endpoint, then something unexpected has happened.
                // This could happen if user code sets an endpoint, but they forgot to add the UseEndpoint middleware.
                var endpoint = context.GetEndpoint();
                var endpointRequestDelegate = endpoint?.RequestDelegate;
                if (endpointRequestDelegate != null)
                {
                    var message =
                        $"The request reached the end of the pipeline without executing the endpoint: '{endpoint.DisplayName}'. " +
                        $"Please register the EndpointMiddleware using '{nameof(IApplicationBuilder)}.UseEndpoints(...)' if using " +
                        $"routing.";
                    throw new InvalidOperationException(message);
                }

                context.Response.StatusCode = 404;
                return Task.CompletedTask;
            };

            foreach (var component in _components.Reverse())
            {
                app = component(app);
            }

            return app;
 }

  • IApplicationBuilder build之后其实就是一个RequestDelegate,能对HttpContext加以处理,默认情况下,管道是空的,就是404;
  • 可以根据需求进行任意的配置,一切全部由开发者自由定制,框架只是提供了一个组装方式
封装中间件

根据源码,可以改进为:

    public class CustomMiddleWare
    {
        private readonly RequestDelegate _next;
        //依赖注入
        public CustomMiddleWare(RequestDelegate next)
        {
            this._next = next;
        }

        public async Task Invoke(HttpContext context)
        {
            await context.Response.WriteAsync($"{nameof(CustomMiddleWare)},Hello World1!<br/>");

            await _next(context);

            await context.Response.WriteAsync($"{nameof(CustomMiddleWare)},Hello World2!<br/>");
        }
    }

注册使用

public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
    app.UseMiddleware<CustomMiddleWare>();
}
进一步封装

使用扩展方法,将这个类中的逻辑作为IApplicationBuilder的扩展方法

public static class MiddleExtend
{
    public static IApplicationBuilder UseCustomMiddleWare(this IApplicationBuilder builder)
    {
        return builder.UseMiddleware<CustomMiddleWare>();
    }
}

注册使用

public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
    app.UseCustomMiddleWare();
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值