.Net Core 3.1之管道中间件

Request请求进来,Middleware1=》Middleware2=》Middleware3,Response返回Middleware3=》Middleware2=》Middleware1

何为中间件?

 1 public class Middleware
 2 {
 3   private readonly RequestDelegate _next;
 4 
 5   public Middleware(RequestDelegate next)
 6   {
 7     _next = next;
 8   }
 9 
10   public Task Invoke(HttpContext httpContext)
11   {
12 
13     return _next(httpContext);
14   }
15 }
16 
17 public delegate Task RequestDelegate(HttpContext context);

构造函数中接受一个RequestDelegate参数,invoke方法中接受HttpCointext参数。简而言之就是Func<RequestDelegate,RequestDelegate>

中间件如何串联?

查看源码!

IApplicationBuilder.Use方法其实就是在往components里添加中间件。

public IApplicationBuilder Use(Func<RequestDelegate, RequestDelegate> middleware)
{
  _components.Add(middleware);
  return this;
}

 IApplicationBuilder.Build方法,先将compoments集合反转循环遍历,把结果作为参数再传给下一个中间件。

 1 public RequestDelegate Build()
 2 {
 3   RequestDelegate app = context =>
 4   {
 5     // If we reach the end of the pipeline, but we have an endpoint, then something unexpected has happened.
 6     // This could happen if user code sets an endpoint, but they forgot to add the UseEndpoint middleware.
 7     var endpoint = context.GetEndpoint();
 8     var endpointRequestDelegate = endpoint?.RequestDelegate;
 9     if (endpointRequestDelegate != null)
10     {
11       var message =
12       $"The request reached the end of the pipeline without executing the endpoint: '{endpoint.DisplayName}'. " +
13       $"Please register the EndpointMiddleware using '{nameof(IApplicationBuilder)}.UseEndpoints(...)' if using " +
14       $"routing.";
15       throw new InvalidOperationException(message);
16     }
17 
18     context.Response.StatusCode = 404;
19     return Task.CompletedTask;
20   };
21 
22 foreach (var component in _components.Reverse())
23   {
24     app = component(app);
25   }
26 
27   return app;
28 }
 1 app.Use(next => {
 2   Console.WriteLine("step 1");
 3   return async c =>
 4   {
 5     await c.Response.WriteAsync("step 1 start");
 6     await next.Invoke(c);
 7     await c.Response.WriteAsync("step 1 end");
 8   };
 9 });
10 
11 app.Use(next => {
12   Console.WriteLine("step 2");
13   return async c =>
14   {
15     await c.Response.WriteAsync("step 2 start");
16     await next.Invoke(c);
17     await c.Response.WriteAsync("step 2 end");
18   };
19 });
20 
21 app.Use(next => {
22   Console.WriteLine("step 3");
23 return async c =>
24 {
25   await c.Response.WriteAsync("step 3 start");
26   // await next.Invoke(c);
27   await c.Response.WriteAsync("step 3 end");
28 };
29 });

结果:

在控制台输出step 3,step 2,step 1       因为有Resverse,合理!

页面输出 step1 start   step 2 start  step 3 start step 3 end step 2 end step 1 end   对应管道模型

原文地址:https://www.cnblogs.com/xingzhu-nan/p/12535272.html