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 依次类推 ----------------

相关文章
相关标签/搜索