定義:中間件是被組裝成一個應用程式管道來處理請求和響應的軟體元件。
上圖是由微軟提供的一個執行圖,我們可以看到有多個中間件,每個中間件請求的時候有個next()方法把職責傳遞給下一個中間件,這裡值得注意的是最後一個中間件沒有next方法,也就是終止,然後響應。
每一個中間件都有它自己的職責,把各個執行分離開執行完成後傳遞給下一個,直到全部的都執行完成,這有點像職責鍊模式。那麼它内部是怎麼實作的呢,下面我們看看
值得注意的是,StartUp類裡面包含兩個方法,ConfigureServices是專門負責容器,Configure是負責http管道方法,是以中間件實在configure方法裡面的。
我們來看看IApplicationBuilder這個裡面有什麼
如上圖所示,我們在使用Use的時候,傳入的中間件添加到委托上,傳入和傳回的都是一個RequestDelegate類型的,當我們進入這個方法的時候,發現它是攜帶HttpContext的
Use、Run 和 Map介紹
Use:上面我們可以看到他裡面傳入的是一個Request Delegate的委托方法,裡面有一個Next()傳遞給下一個中間件的方法,如果該方法不執行,那麼下面的中間件也是不會執行的,我們稱之為短路中間件。
Run:是一種約定,并且某些中間件元件可公開在管道末尾運作的
Run[Middleware]
方法。
Map:擴充用作約定來建立管道分支。
Map*
基于給定請求路徑的比對項來建立請求管道分支。 如果請求路徑以給定路徑開頭,則執行分支。
下面我們來看看短路中間件
// This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
public void Configure(IApplicationBuilder app, IHostingEnvironment env)
{
app.Use(async (context,next)=>
{
await context.Response.WriteAsync("use\n");
//await next.Invoke();
});
app.Run(async (context) =>
{
await context.Response.WriteAsync("run");
});
}
我們來自定義一個中間件
//這是我們的中間件
public class UseTestMiddleWare
{
private readonly RequestDelegate _next;
public UseTestMiddleWare(RequestDelegate next)
{
_next = next;
}
public async Task Invoke(HttpContext context)
{
await context.Response.WriteAsync("invoke\n");
await _next.Invoke(context);
}
}
//我們需要把中間件添加到擴充裡面才能使用它
public static class UseTestMiddleWareExtensions
{
public static IApplicationBuilder UseTestMiddleWare(this IApplicationBuilder builder)
{
return builder.UseMiddleware<UseTestMiddleWare>();
}
}
調用:
// This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
public void Configure(IApplicationBuilder app, IHostingEnvironment env)
{
app.UseTestMiddleWare();
app.Run(async context =>
{
await context.Response.WriteAsync("hello");
});
}