01-001 HttpAbstractions 01 IApplicationBuilder

 

本文基於 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 依次類推 ----------------

相關文章
相關標籤/搜索