本文基于 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 依次类推 ----------------