此文是在官方文档的基础上做的个人总结,一些简单的内容就没用再列出来了,参考官方文档:https://docs.microsoft.com/zh-cn/aspnet/core/fundamentals/middleware/write?view=aspnetcore-5.0
中间件是一种装配到应用管道用来处理请求与响应的组件。在前面的文章中我们介绍了框架自带的一些中间件,这次我们来介绍下如何自定义中间件。
一般有两种方式可以自定义中间件,会分别详细介绍:
- 基于约定创建
- 基于
IMiddleware
接口创建
具体的约定是:
- 中间件类必须要有参数为
RequestDelegate
的公有构造函数 - 必须要有名字为
Invoke
或InvokeAsync
的公共方法,这个方法必须返回Task
且方法的第一个参数类型是HttpContext
.
1.1自定义中间件
首先自定义一个中间件类:
public class RequestCultureMiddleware
{
private readonly RequestDelegate _next;
public RequestCultureMiddleware(RequestDelegate next)
{
_next = next;
}
public async Task InvokeAsync(HttpContext context, ILogger<RequestCultureMiddleware> logger)
{
var cultureQuery = context.Request.Query["culture"];
if (!string.IsNullOrWhiteSpace(cultureQuery))
{
var culture = new CultureInfo(cultureQuery);
CultureInfo.CurrentCulture = culture;
CultureInfo.CurrentUICulture = culture;
}
// Call the next delegate/middleware in the pipeline
await _next(context);
}
}
然后在Configure
方法中配置即可(当然也可以把这个UseMiddleware
放到IApplicationBuilder
的扩展方法里):
//括号里也可以跟入参数,会传入构造函数中
app.UseMiddleware<RequestCultureMiddleware>();
1.2 中间件传参数的几种方法
中间件是在应用程序启动时构造的,而且只会构造一次。
- 构造函数的入参,支持从DI容器中解析。
-
InvokeAsync
方法的入参也支持从DI容器中解析,而且每次请求(per-request)时都会解析。 - 也可以通过
UseMiddleware<T>(params object[] args)
传入其他参数。
IMiddleware
接口的中间件
如基于约定的中间件实现步骤不同,我们也可以通过实现IMiddleware
接口来自定义中间件:
写一个类实现IMiddleware
接口:
public class MyMiddleware : IMiddleware
{
ILogger<MyMiddleware> _logger;
public MyMiddleware(ILogger<MyMiddleware> logger)
{
_logger = logger;
}
public async Task InvokeAsync(HttpContext context, RequestDelegate next)
{
_logger.LogInformation("----->MyMiddleware Invoked");
await next(context);
}
}
然后在configureService
方法中注册服务:
services.AddTransient<MyMiddleware>();
然后在configure
方法中添加use:
//因为MyMiddleware对象是DI容器构造的,所以这里即使传入参数也没用
app.UseMiddleware<MyMiddleware>();