.Net基础系列(三):自定义中间件

107 阅读1分钟

问题

如果需要在C#项目中自定义中间件,该如何实现呢?

前置条件

  • 基于.Net 6.0创建的C# Demo
  • 主要目录结构如下
DemoApplication
    |---> src
           |---> controller folder
           |---> service folder
           |---> Program.cs
           |---> Middleware.cs

中间件

C#项目中有两种类型的中间件,一种是系统提供的默认的中间件,一种是用户自定义的中间件。中间件作用于入口程序到Controller层之间,如下图所示:

flowchart LR
    A0[Program.cs] --> |config| M0[default Middleware]
    A0[Program.cs] --> |config| M1[custom Middleware]
    M0 --> A[Controller]
    M1 --> A
   

自定义中间件

自定义中间件Middleware.cs,在构造函数中传入RequestDelegate对象,然后实现InvokeAsync方法,在方法实现具体的逻辑。最后将context传递下去。

// Middleware.cs
public class CustomMiddleware
{
    private readonly RequestDelegate _next;
    
    public CustomMiddleware(RequestDelegate next)
    {
        _next = next;
    }
    
    // system defined InvokeAsync
    public async Task InvokeAsync(HttpContext context)
    {
        Console.WriteLine("This is Custom Middleware...");
        doSomething();
        await _next(context);
    }
}

Program.cs文件中引用自定义的中间件CustomMiddleware

// Program.cs
var builder = WebApplication.CreateBuilder(args);
var app = builder.Build();
// 配置中间件
app.UseMiddleware<CustomMiddleware>();

在中间件中调用Service层的方法

在中间件中可以使用IServiceScopeFactory来调用Service层的方法。在构造函数中以参数的方式传入IServiceScopeFactory,然后在具体的方法中通过_serviceScopeFactory.CreateScope().ServiceProvider.GetRequiredService来调用具体的service服务。

示例如下:

// Middleware.cs
public class CustomMiddleware
{
    private readonly RequestDelegate _next;
    private readonly IServiceScopeFactory _serviceScopeFactory;
    
    public CustomMiddleware(RequestDelegate next, IServiceScopeFactory serviceScopeFactory)
    {
        _serviceScopeFactory = serviceScopeFactory;
        _next = next;
    }

    public async Task InvokeAsync(HttpContext context)
    {
        // 这里
        using var scope = _serviceScopeFactory.CreateScope();
        var service = scope.ServiceProvider.GetRequiredService<ICustomService>();
        service.method();
        await _next(context);
    }
}