1. 中间件的概述

中间件是一种装配到应用管道以处理请求和响应的组件。 每个组件:

  • 选择是否将请求传递到管道中的下一个组件。
  • 可在管道中的下一个组件前后执行工作。

请求委托用于生成请求管道。 请求委托处理每个 HTTP 请求。

中间件是构成请求管道的基石

2. 与Framework中IHttpModule的比较

IHttpModule和IHttpHandler在管道里的执行示意

Resin中间件干嘛用_自定义

中间件在管道里的执行示意

Resin中间件干嘛用_中间件_02

参考自定义IHttpHandler和自定义IHttpModule

参考MSDN IHttpHandler和IHttpModule迁移到中间件

  • 中间件更简单

1.模块、处理程序、 Global.asax.cs、 Web.config (IIS 配置除外)和应用程序生命周期已消失

2.中间件已使用模块和处理程序的角色

3.中间件使用代码而不是Web.config来配置

  • 中间件更灵活

通过管道时,你可以将请求发送到特定的中间件,不仅可以基于 URL,还可以发送到请求标头、查询字符串等。

  • 中间件非常类似于IHttpModule
  • 按指定的规则,为每个请求按分配
  • 阻止将请求传递给下一个中间件,来对请求进行短路(短路指:停止将请求传递给下一个中间件,对客户端响应)
  • 能够创建自己的 HTTP 响应
  • 中间件和IHttpModule按不同的顺序进行处理
  • 中间件的顺序取决于它们插入请求管道的顺序,而IHttpModule的顺序主要基于应用程序生命周期事件
  • 中间件响应的顺序与请求的顺序相反。IHttpModule中,对于请求和响应,顺序是相同的。

3. 基于约定实现一个中间件

  • 中间件生命周期默认为单例
public class LogMiddleWare
{
    private readonly RequestDelegate _next;
    public LogMiddleWare(RequestDelegate next)
    {
        _next = next;
    }

    public async Task InvokeAsync(HttpContext context)
    {
        await _next(context);
    }

}

4. 基于接口实现一个中间件

  • 生命周期可自定义
public class UpgradeLogMiddleWare : IMiddleware
{
    public async Task InvokeAsync(HttpContext context, RequestDelegate _next)
    {
         await _next(context);
    }
}

5. 将中间件加入请求管道

通过IApplicationBuilder 接口加入管道,提供了多个方法:

Use、Run、Map、MapWhen、UseMiddleware

底层都是用到了Use。

一般使用UseMiddleware,因为其提供了DI(依赖注入)的功能。

6. 中间件传递请求

Resin中间件干嘛用_中间件_03

本质是通过RequestDelegate,传递HttpContenxt。

下面的动态图,方便更好的理解

Resin中间件干嘛用_自定义_04

7. 中间件和过滤器的比较

红色的线表示中间件的请求,蓝色的表示Filter的请求。

Resin中间件干嘛用_生命周期_05

无关MVC/API上下文,则使用中间件,达到缩短管道流程的目的。

参考源码:StaticFileExtensions.UseStaticFiles

8. 终端中间件

请求管道中的每个中间件组件负责调用管道中的下一个组件,或使管道短路。 当中间件短路时,它被称为“终端中间件”,因为它阻止中间件进一步处理请求。

Resin中间件干嘛用_自定义_06