尧图网站建设 尧图网络
  • 首页
  • 关于我们
  • 服务项目
  • 案例展示
  • 建站流程
  • 资讯中心
  • 联系我们
首页/资讯中心/详情

自定义中间件进入管道中执行队列的流程

自定义中间件进入管道中执行队列的流程
📅 发布时间:2026/6/20 16:32:22

自定义中间件进入管道中执行队列的流程

1. 自定义中间件类的标准写法

public class CustomLoggingMiddleware
{private readonly RequestDelegate _next;// 1. 构造函数必须包含 RequestDelegate next 参数public CustomLoggingMiddleware(RequestDelegate next){_next = next;}// 2. 必须包含名为 Invoke 或 InvokeAsync 的公共方法public async Task InvokeAsync(HttpContext context){//执行前动作...// 调用管道中的下一个中间件await _next(context);       //执行后动作...}
}

2. 使用扩展方法注册中间件

public static class CustomLoggingMiddlewareExtensions
{public static IApplicationBuilder UseCustomLogging(this IApplicationBuilder app){return app.UseMiddleware<CustomLoggingMiddleware>();}
}

3. 在管道中使用

public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{app.UseCustomLogging();  // 我们的自定义中间件app.UseHttpsRedirection();app.UseStaticFiles();app.UseRouting();app.UseAuthorization();app.MapControllers();
}

4. 转换流程详解

现在来看 UseMiddleware<CustomLoggingMiddleware>() 是如何将类转换成管道方法的:

步骤 1: UseMiddleware<T> 扩展方法
// Microsoft.AspNetCore.Builder.UseMiddlewareExtensions
public static class UseMiddlewareExtensions
{public static IApplicationBuilder UseMiddleware<TMiddleware>(this IApplicationBuilder app){return app.UseMiddleware(typeof(TMiddleware));}public static IApplicationBuilder UseMiddleware(this IApplicationBuilder app, Type middlewareType){// 创建中间件工厂return app.Use(next =>{// 这里就是转换的关键!// 创建一个委托,它会在每次请求时实例化中间件并调用Invoke方法var middlewareFactory = (IMiddlewareFactory)app.ApplicationServices.GetService(typeof(IMiddlewareFactory));return async context =>{// 每次请求都会执行这个委托var middleware = middlewareFactory.Create(middlewareType);try{// 调用中间件的InvokeAsync方法await middleware.InvokeAsync(context, next);}finally{middlewareFactory.Release(middleware);}};});}
}
步骤 2: 运行时实际生成的委托

实际上,ASP.NET Core 使用更高效的代码生成机制。简化后的等效代码:

// 运行时生成的委托大致如下:
Func<RequestDelegate, RequestDelegate> generatedMiddleware = next =>
{return async context =>{// 创建中间件实例var middleware = new CustomLoggingMiddleware(next, logger);// 调用InvokeAsync方法await middleware.InvokeAsync(context);};
};
步骤 3: 管道构建过程
// 初始管道终点
RequestDelegate pipelineEnd = async context => 
{context.Response.StatusCode = 404; // 默认404
};// 应用我们的自定义中间件
var customMiddleware = generatedMiddleware(pipelineEnd);// 最终生成的委托
RequestDelegate finalPipeline = async context =>
{var logger = // 获取logger实例;var middlewareInstance = new CustomLoggingMiddleware(pipelineEnd, logger);await middlewareInstance.InvokeAsync(context);
};
完整的转换流程图示
自定义中间件类↓
UseMiddleware<T>() 扩展方法↓
反射分析中间件类的构造函数和方法↓
生成优化的委托代码 (Func<RequestDelegate, RequestDelegate>)↓
注册到 IApplicationBuilder 的中间件列表↓
管道构建时被包装成最终的 RequestDelegate↓
请求到达时执行生成的委托代码

支持多种方法签名的中间件

ASP.NET Core 支持多种方法签名,转换器会智能处理:

方式 1: 标准的 InvokeAsync 方法

csharp

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

方式 2: 带服务的 InvokeAsync 方法

csharp

public async Task InvokeAsync(HttpContext context, ISomeService service)
{// 依赖注入会自动注入服务await _next(context);
}

方式 3: 同步的 Invoke 方法

csharp

public void Invoke(HttpContext context)
{// 同步处理_next(context).Wait();
}

实际的复杂中间件示例

csharp

public class RateLimitingMiddleware
{private readonly RequestDelegate _next;private readonly IMemoryCache _cache;private readonly RateLimitOptions _options;// 构造函数注入public RateLimitingMiddleware(RequestDelegate next, IMemoryCache cache, IOptions<RateLimitOptions> options){_next = next;_cache = cache;_options = options.Value;}// 方法参数注入public async Task InvokeAsync(HttpContext context, ILogger<RateLimitingMiddleware> logger){var clientIp = context.Connection.RemoteIpAddress?.ToString();var cacheKey = $"rate_limit_{clientIp}";// 速率限制逻辑if (_cache.TryGetValue(cacheKey, out int requestCount) && requestCount >= _options.MaxRequests){logger.LogWarning("IP {IP} 触发速率限制", clientIp);context.Response.StatusCode = 429;await context.Response.WriteAsync("Too Many Requests");return;}// 更新计数器_cache.Set(cacheKey, requestCount + 1, TimeSpan.FromMinutes(1));await _next(context);}
}public class RateLimitOptions
{public int MaxRequests { get; set; } = 100;
}

依赖注入的自动处理

转换过程中,依赖注入容器会自动处理:

csharp

// 转换器会分析构造函数和方法参数
public async Task InvokeAsync(HttpContext context, ILogger<RateLimitingMiddleware> logger,        // 方法参数注入IMemoryCache cache,                            // 方法参数注入  IOptions<RateLimitOptions> options)            // 方法参数注入
{// 所有这些参数都会从DI容器自动解析
}

10. 总结:转换流程的关键步骤

  1. 类定义:创建带有 RequestDelegate 参数构造函数和 Invoke/InvokeAsync 方法的类
  2. 扩展方法注册:通过 UseMiddleware<T> 注册到管道
  3. 反射分析:框架分析中间件类的构造函数和方法签名
  4. 委托生成:生成优化的 Func<RequestDelegate, RequestDelegate> 委托
  5. 管道构建:在 Build() 方法中被包装到管道中
  6. 请求执行:每次请求时创建中间件实例并调用相应方法

这种设计的好处:

  • 类型安全:编译时检查中间件签名
  • 依赖注入:自动处理服务生命周期
  • 性能优化:使用代码生成而非纯反射
  • 灵活性:支持多种方法签名和参数注入方式

相关新闻

  • .net8+winform+Antdui 制作 LOL 小助手
  • 深入解析:【Git】Git 简介及基本操作
  • 20250916_QQ_Powershell

最新新闻

  • 深度解析ComfyUI-Impact-Pack架构演进与Switch节点兼容性优化方案
  • 昆明黄金回收鉴定师资质排名:持证vs无证,差距有多大? - charlieruizvin
  • 把日子过成自己喜欢的样子
  • 深圳南山葡萄牙语培训哪家值得推荐 - 速递信息
  • 深圳汉语培训哪个好 - 速递信息
  • 如何将数字文本转换为逼真手写体:开源工具 text-to-handwriting 的完整指南

日新闻

  • 信任的进化:技术实现详解——如何用JavaScript构建博弈论模拟器
  • Terrakube自定义工作流:如何集成OPA、Infracost等工具扩展IaC能力
  • grunt-concurrent快速入门:5分钟学会并行运行Grunt任务

周新闻

  • 3步解锁iOS设备:applera1n激活锁绕过完全指南
  • 39 2026 人工智能证书终极盘点,普通人选 AI 证书可以从这些方向入手
  • Redis 暴露公网有多危险?从端口检查到补救步骤

月新闻

  • 【总结】入门篇:50句话让你记住架构核心概念
  • WeChatMsg技术方案解析:实现Mac微信数据自主管理的完整解决方案
  • WeChatMsg:革新性微信数据备份方案,打造你的专属数字记忆库

关于尧图

  • 公司简介
  • 团队介绍
  • 企业文化
  • 荣誉资质

服务项目

  • 定制开发
  • 电商建站
  • UI 设计
  • 运维服务

快速链接

  • 案例展示
  • 建站流程
  • 常见问题
  • 资讯中心

联系方式

  • 📍北京市朝阳区互联网产业园 A 座 10 层
  • 📞400-888-8888
  • ✉️contact@rkmt.cn
  • 🕐周一至周日 9:00-21:00

© 2024 北京尧图网络科技有限公司 版权所有 | 京 ICP 备 XXXXXXXX 号