但愿给你3-5分钟的碎片化学习,多是坐地铁、等公交,聚沙成塔,水滴石穿,谢谢关注。html
咱们知道一个管道能够有一个或多个中间件,而中间件的职责是根据HttpContext处理HTTP请求,而后往Response里填充东西,最后完成整个Response的输出。了解管道流机制,就能知道如何利用管道进行拦截,自定义封装中间件等高级操做,因此学习管道流机制对咱们编码有质的提升。那么管道数据是如何流通的呢?以下图所示,Request进入Middleware 1,叠加一层逻辑代码到HttpContext(切确说是HttpContext的Response对象),而后调用next()进入到下一个Middleware 2,依次递推,最后全部的逻辑代码叠加完毕后返回前端。前端
IApplicationBuilder构建管道有两种方法,分别是Use和Run方法,他们的区别在下面会谈到。app
这里先了解Use方法的第一个重载,以下图所示,他是一个类型为委托的中间件(middleware)。async
这个中间件同时携带一个next的RequestDelegate委托,能够实现调用下一个管道中间件,咱们看下代码实践,以下所示,context从当前管道进来,处理后,经过next.Invoke()转移到下一个管道,完成一个管道的生命周期。ide
其实我更喜欢截图,由于能够任意打标注,可是不方便拷贝,因此一块儿贴上代码吧。学习
app.Use(async (context, next) => { await context.Response.WriteAsync("fisrt……"); await next.Invoke(); });
以上的用法,若是是新手可能不知其因此然,用没问题,可是内部是如何实现的?不知道!其实这里使用到了语言的高级特性委托,经过委托实现了开闭原则,也就是把管道的扩展开放出来,咱们可使用规定的app.Use方法,可是内部定义的委托参数类型,好比context,Fun<task>则对外屏蔽了实现。因此你看到的next.Invoke()已经封装了具体的实现了,对于使用者,其实能够不用去管那么多,拿来用便可。ui
app.Use还有另一个重载,以下图提示:这里Func传入一个RequestDelegate,返回一个RequestDelegate。不一样于第一个重载,他没有next.Invoke()的调用,而是之间返回一个RequestDelegate给app进行处理。编码
咱们看下代码实现,外层红色框是传入的管道,内部绿色框是返回的管道。spa
app.Run和app.Use不一样之处在于,app.Use能够调用下一个管道中间件,app.Run不会,咱们演示一段代码。code
app.Use(async (context, next) => { await context.Response.WriteAsync("<html><body>"); await context.Response.WriteAsync("<div>Inside middleware defined using app.Use</div>"); await next(); await context.Response.WriteAsync("</body></html>"); }); app.Run(async context => { await context.Response.WriteAsync("<div>Inside middleware defined using app.Run</div>"); });
//该管道会不会被打印呢? app.Use(async (context, next) => { await context.Response.WriteAsync("<html><body>"); await context.Response.WriteAsync("<div>Another Middleware defined using app.Use</div>"); await next(); await context.Response.WriteAsync("</body></html>"); });
以下图所示,咱们看到Run后面定义的第二个Use没有打印出来,这是由于Run不会调用随后的管道中间件致使的,因此咱们通常习管性把Run方法放在全部管道中间件的最后。
但愿以上分享对你有帮助,我是IT人张飞洪,入行10年有余,人不堪其忧,吾不改其乐,谢谢您关注