田敏
返回博客列表
技术

🧭 ASP.NET Core 中间件实现方式总结笔记

田敏
2025-10-302 分钟阅读
.NETC#Backend

🧭 ASP.NET Core 中间件实现方式总结笔记

一、📘 中间件的基本概念

  • 中间件(Middleware) 是 ASP.NET Core 请求处理管道中的一个组件。
  • 每个中间件负责处理部分请求逻辑,并决定是否将请求传递给下一个中间件。
  • 常见功能:日志记录、认证授权、异常捕获、CORS、静态文件处理等。

⚙️ 核心原理: ASP.NET Core 通过一个 请求委托链(RequestDelegate) 来依次调用中间件。


二、🧩 中间件的两种实现方式

| 类型 | 是否需要实现接口 | 注册方式 | 特点 | | ------------------------------- | ----------------------------- | ------------------------------------------------- | -------------------------------- | | 委托式中间件(常规写法) | ❌ 不需要实现接口 | app.UseMiddleware<T>() | 简单直接,最常用 | | 接口式中间件(IMiddleware) | ✅ 需要实现 IMiddleware 接口 | 需先在 DI 中注册,然后 app.UseMiddleware<T>() | 生命周期受 DI 管理,更灵活可复用 |


三、✍️ 方式一:委托式中间件(推荐写法)

✅ 示例:

public class SwaggerAuthMiddleware
{
    private readonly RequestDelegate _next;
    private readonly AuthOptions _options;

    public SwaggerAuthMiddleware(RequestDelegate next, IOptions<AuthOptions> options)
    {
        _next = next;
        _options = options.Value;
    }

    public async Task InvokeAsync(HttpContext context)
    {
        if (!_options.Enabled || !context.Request.Path.StartsWithSegments("/swagger"))
        {
            await _next(context);
            return;
        }

        // 身份验证逻辑 ...
    }
}

✅ 注册:

app.UseMiddleware<SwaggerAuthMiddleware>();

✅ 特点:

  • 不需要实现接口;
  • 框架自动识别具有 InvokeInvokeAsync(HttpContext) 的类为中间件;
  • 支持构造函数注入;
  • 简单高效,官方推荐写法

四、✍️ 方式二:接口式中间件(IMiddleware 写法)

✅ 示例:

public class SwaggerAuthMiddleware : IMiddleware
{
    private readonly AuthOptions _options;

    public SwaggerAuthMiddleware(IOptions<AuthOptions> options)
    {
        _options = options.Value;
    }

    public async Task InvokeAsync(HttpContext context, RequestDelegate next)
    {
        if (!_options.Enabled)
        {
            await next(context);
            return;
        }

        // 身份验证逻辑 ...
    }
}

✅ 注册:

services.AddTransient<SwaggerAuthMiddleware>();
app.UseMiddleware<SwaggerAuthMiddleware>();

✅ 特点:

  • 必须在依赖注入容器(DI)中注册;
  • 生命周期可由 AddTransient / AddScoped / AddSingleton 控制;
  • 更适合:
    • 复杂的业务组件;
    • 依赖多种服务;
    • 需要通过构造函数注入作用域对象(如 DbContext、UserManager);
    • 可在多个项目中重用。

五、⚖️ 两种写法的对比总结

| 对比项 | 普通中间件 | IMiddleware 实现 | | ------------ | --------------------------------- | -------------------------------------- | | 接口要求 | 无需接口 | 必须实现接口 | | 框架识别方式 | 自动识别 Invoke / InvokeAsync | 通过 DI 容器创建 | | 依赖注入 | 支持构造函数注入 | 支持构造函数注入 | | 生命周期控制 | 固定(每次请求新建实例) | 可由 DI 控制 | | 适合场景 | 简单、一次性中间件 | 可复用、依赖复杂服务的中间件 | | 注册复杂度 | 直接 UseMiddleware | 需先 AddTransientUseMiddleware |


六、🧠 框架识别机制

ASP.NET Core 判断一个类是否是中间件的依据是:

  1. 类的构造函数中包含 RequestDelegate next 参数;

  2. 类中存在:

    Task Invoke(HttpContext context)
    

    Task InvokeAsync(HttpContext context)
    
  3. 如果实现了 IMiddleware 接口,则会从 DI 容器中获取实例。


七、🧱 典型中间件执行顺序图

请求进来
   ↓
[Middleware A]
   ↓
[Middleware B]
   ↓
[Middleware C]
   ↓
终端(控制器 / Razor 页面 / Swagger)
   ↑
   └── 响应依次反向经过中间件链

八、📎 实际开发建议

推荐默认使用委托式中间件 简单、清晰,适合绝大多数场景。

当中间件需要被复用或依赖多层服务时 再考虑使用 IMiddleware

不要混用两种风格 同一个中间件保持一致的写法,方便维护。

保持职责单一 一个中间件只做一件事(认证、日志、异常等)。


九、🧰 小结口诀

🔹 “有 Invoke 就是中间件, 🔹 IMiddleware 管生命周期, 🔹 简单逻辑用普通类, 🔹 复杂依赖交给 DI。”

版权协议:MIT返回列表