本文基於 beta5 版本 github 源碼連接:https://github.com/aspnet/Home/releases html
asp.net5 中有個重要的 Delegate:git
public delegate Task RequestDelegate(HttpContext context);
輸入參數爲:HttpContext 返回 Task ;github
凡是須要處理HttpContext的事情(能夠稱做中間件:Middleware) 均可以抽象爲 RequestDelegate;跨域
好比:緩存
1.根據請求路徑訪問目錄的默認文件(如index.html default.htm 等),: DefaultFilesMiddlewareapp
2.瀏覽文件夾中的文件 (列出文件夾中的目錄和文件) :DirectoryBrowserMiddlewareasp.net
3.發送(下載)靜態文件:SendFileMiddleware 主要是設置文件寫到流中的Featureide
4.根據請求處理靜態文件:StaticFileMiddleware 如:部分請求; 緩存未失效 返回304狀態;只是Head請求 返回狀態碼 等;ui
5. 增長Session支持功能:SessionMiddlewarethis
6. 增長錯誤處理功能:ErrorHandlerMiddleware
7. 表單驗證功能:CookieAuthenticationMiddleware
8. 路由功能 :RouteMiddleware
9.跨域訪問功能:CorsMiddleware
等等 這些中間件中都有個方法:
public Task Invoke(HttpContext context){}
使用這個Delegate 的一個接口是: IApplicationBuilder
在asp.net5 中 IApplicationBuilder 是一個很重要的接口
操做HttpContext的全部的中間件都要經過 Use 方法來登記使用:
此接口 有6個成員 三個屬性 Server ApplicationServices Properties 三個方法 New Use Build. 源碼以下:
public interface IApplicationBuilder { IServiceProvider ApplicationServices { get; set; } object Server { get; } IDictionary<string, object> Properties { get; } IApplicationBuilder Use(Func<RequestDelegate, RequestDelegate> middleware); IApplicationBuilder New(); RequestDelegate Build(); }
對應的默認實現類是:
public class ApplicationBuilder : IApplicationBuilder{}
IServiceProvider 這個接口 有一個成員: object GetService(Type serviceType);
這個成員來自系統建立時候賦值:
public ApplicationBuilder(IServiceProvider serviceProvider)
{
Properties = new Dictionary<string, object>();
ApplicationServices = serviceProvider;
}
New 方法 新建立一個IApplicationBuilder. 在ApplicationBuilder中實現以下:
public IApplicationBuilder New() { return new ApplicationBuilder(this); } private ApplicationBuilder(ApplicationBuilder builder) { Properties = builder.Properties; }
Use 方法實現以下:
private readonly IList<Func<RequestDelegate, RequestDelegate>> _components = new List<Func<RequestDelegate, RequestDelegate>>(); public IApplicationBuilder Use(Func<RequestDelegate, RequestDelegate> middleware) { _components.Add(middleware); return this; }
Func<RequestDelegate, RequestDelegate> 舉個例子: Use(nextRequestDelegate=> return currentRequestDelegate);
最後看一下Build 方法的實現:
public RequestDelegate Build() { RequestDelegate app = context => { context.Response.StatusCode = 404; return Task.FromResult(0); }; foreach (var component in _components.Reverse()) { app = component(app); } return app; }
component :Func<RequestDelegate, RequestDelegate>
若是沒有添加任何的 middleware (component)系統默認返回 404 狀態。
若是添加了一個,好比:DefaultFilesMiddleware
便是調用了 Use(next => return new DefaultFilesMiddleware(...).Invoke );
若是再添加了一個,好比:StaticFileMiddleware
即便調用了 Use(next=>return new StaticFileMiddleware (...).Invoke);
component 能夠根據須要退出 或者繼續執行後面的 RequestDelegate 。最後一個是 返回404狀態的 RequestDelegate.
若是有多箇中間件 如 C1 C2 C3 則實現了這個的結構
返回的 DelegateRequest=C1 (C2 ( C3 (404RequestDelegate) ))到調用的時候 C1 先調用 能夠選擇結束 返回 或者 繼續調用C2 依次類推 ----------------