上一篇我们讲了Startup文件,其中着重介绍了中间件,现在我们就来自定义我们自己的中间件吧。
中间件通常封装在一个类中,并使用扩展方法进行暴露。它需要拥有一个类型为RequestDelegate的成员变量,通常定义为 private RequestDelegate _next ; 然后通过在构造函数中注入RequestDelegate,还需要有一个Invoke方法供Asp.Net Core调用。
先看代码吧,我们定义了一个日志中间件
using Microsoft.AspNetCore.Http; using Microsoft.Extensions.Logging; using System; using System.Collections.Generic; using System.Globalization; using System.Linq; using System.Threading.Tasks; namespace WebApplication1.MiddleWare { /// <summary> /// 自定义日志中间件 /// </summary> public class LoggerMiddleWare { private RequestDelegate _next; public LoggerMiddleWare(RequestDelegate next) { _next = next; } public async Task Invoke(HttpContext context) { context.Response.ContentType = "text/plain;charset=utf-8;"; await context.Response.WriteAsync("this is my custom logger before;"); // Call the next delegate/middleware in the pipeline await this._next(context); await context.Response.WriteAsync("this is my custom logger after;"); } } }
然后通过扩展方法将其暴露出来给ApplicationBuilder调用
using Microsoft.AspNetCore.Builder; using Microsoft.AspNetCore.Http; using Microsoft.Extensions.Logging; using System; using System.Collections.Generic; using System.Linq; using System.Threading.Tasks; using WebApplication1.MiddleWare; namespace WebApplication1.Extension { public static class LoggerMiddlerWareExtension { public static IApplicationBuilder UseLogger(this IApplicationBuilder builder) { return builder.UseMiddleware<LoggerMiddleWare>(); } } }
在Startup文件中Configure方法添加如下语句
app.UseLogger(); app.Run(async (context) => { await context.Response.WriteAsync( $"Hello {CultureInfo.CurrentCulture.DisplayName}"); });
运行结果
中间件应该遵循显式依赖原则,通过在其构造函数中暴露其依赖关系。
因为中间件是在应用程序启动时构建的,而不是每个请求,所以在每个请求期间,中间件构造函数使用的作用域生命周期服务不会与其他依赖注入类型共享。 如果需要在中间件和其他类型之间共享作用域服务,请将这些服务添加到Invoke方法的签名中。 Invoke方法可以接受由依赖注入填充的其他参数。