1. 程式人生 > >asp.net core 中間件粗解

asp.net core 中間件粗解

實現 繼續 sta when 演示 集合 style add 字段

中間件

中間件在asp.net core中非常重要,它用來處理httpcontext。而httpcontext封裝了請求和響應。也就是說,中間件是用來處理請求和響應的。

本質上,中間件被封裝到了IApplicationBuilder這個接口中,他的實現類是ApplicationBuilder。源碼在github:https://github.com/aspnet/HttpAbstractions

ApplicationBuilder有兩個方法和一個字段比較重要:

private readonly IList<Func<RequestDelegate, RequestDelegate>> _components = new
List<Func<RequestDelegate, RequestDelegate>>();
 public IApplicationBuilder Use(Func<RequestDelegate, RequestDelegate> middleware)
        {
            _components.Add(middleware);
            return this;
        }
public RequestDelegate Build()
        {
            RequestDelegate app 
= context => { context.Response.StatusCode = 404; return Task.CompletedTask; }; foreach (var component in _components.Reverse()) { app = component(app); } return app; }

這個_components字段就是中間件的一個集合,在Startup類中,通過app.Use()和Run()還有Use***MIddleware等擴展方法,在背後是通過ApplicationBuilder這個類的本身的Use方法來轉換成一個Func<RequestDelegate,RequestDelegate>,然後添加到_components這個字段上的。比如說我們會在Startup類中寫這樣的中間件(毫無意義的代碼,純粹是為了演示):

 app.Use(async (context, next) =>
            {
                await context.Response.WriteAsync("when a \n");
                await next();
                await context.Response.WriteAsync("after a \n");
            });

這段代碼中,app.Use是一個擴展方法,給這個方法傳入了一個Func<HttpContext,Func<Task>,Task>,而這個擴展方法如下:

public static IApplicationBuilder Use(this IApplicationBuilder app, Func<HttpContext, Func<Task>, Task> middleware)
        {
            return app.Use(next =>
            {
                return context =>
                {
                    Func<Task> simpleNext = () => next(context);
                    return middleware(context, simpleNext);
                };
            });
        }

在這個擴展方法的內部,還是最終調用了ApplicationBuilder的Use方法(不是擴展方法),這個方法在內部通過Func<Task> simpleNext = () => next(context);這段代碼把傳入的Func<HttpContext, Func<Task>, Task>中的Func<Task>參數轉化成了內部的調用(有一些拗口,意思就是轉化了一下,以便這個中間件能夠繼續調用HttpContext)最終,才調用傳入的middleware。然後,將這個委托返回,最終,添加到了_component字段上面。

asp.net core 中間件粗解