希望给你3-5分钟的碎片化学习,可能是坐地铁、等公交,积少成多,水滴石穿,谢谢关注。

管道实现机制

要了解管道的实现机制,我们必须要深入框架的源码,幸亏微软开源了,我们可以访问GitHub的地址来下载源码。

git clone后,我们打开工程,进入Microsoft.AspNetCore.Http项目搜索ApplicationBuilder类(如下图),RequestDelegate是中间件的核心,而ApplicationBuilder是接收多个RequestDelegate的集合,所以解析ApplicationBuilder是了解整个管道实现的重要内容。而ApplicationBuilder里有两个重要的方法Build和Use也是我们关注的焦点。

   

Use方法

  

  我们看下Use方法的参数是一个委托,该委托接收一个RequestDelegate参数,返回一个RequestDelegate,而_components.Add(middleware);是什么呢?我们看下这个全局变量的定义:

  

   _components就是一个IList列表容器,也就是说Use方法做的事情非常简单,就是不断的把中间件middleware往容器里面加而已,而中间件是什么?就是一个由RequestDelegate构成的委托罢了。   

  我们知道Use还有一个重载方法,他是一个扩展方法,可以在UseExtensions找到(如下图),这个扩展方法其实也是调用上面的Use方法,往容器添加内容。

  

  包括Run方法和上面类似,都是往容器灌入Middleware中间件。

  

Build方法

  Use完了之后,接下来做什么呢?我们看下Build实现代码。

  

  这里对RequestDelegate集合进行反转,然后逐一调用执行,所以app会被最后一个执行。最后只返回一个RequestDelegate

模拟构建管道

  接下来,我们来模拟管道的构建过程,我们先建两个类,一个是RequestDelegate.cs和HttpContext.cs。

  

  HttpContext.cs我们假设没有任何实现:

  

  RequestDelegate.cs定义一个委托

  

  因为是模拟,所以我们这里使用控制台来测试,dotnet new console --name iConsole

  我们在Program.cs实现核心代码如下:

  1. using System;
  2. using System.Collections.Generic;
  3. using System.Threading.Tasks;
  4.  
  5. namespace iConsole
  6. {
  7. class Program
  8. {
  9. private static readonly IList<Func<RequestDelegate, RequestDelegate>> _mycomponents =
  10. new List<Func<RequestDelegate, RequestDelegate>>();
  11.  
  12. static void Main(string[] args)
  13. {
  14. //以下是Lambada表达式的简写
  15. Use(next =>
  16. {
  17. return context =>
  18. {
  19. Console.WriteLine("PipeLine 1……");
  20. return next.Invoke(context);
  21. };
  22. });
  23.  
  24. Use(next =>
  25. {
  26. return context =>
  27. {
  28. Console.WriteLine("PipeLine 2……");
  29. return next.Invoke(context);
  30. };
  31. });
  32.  
  33. RequestDelegate PipeLine_end = context =>
  34. {
  35. Console.WriteLine("PipeLine_end……");
  36. return Task.CompletedTask;
  37. };
  38.  
  39. foreach (var component in _mycomponents)
  40. {
  41. PipeLine_end = component(PipeLine_end);
  42. }
  43.  
  44. PipeLine_end.Invoke(new HttpContext());
  45.  
  46. Console.ReadLine();
  47. }
  48.  
  49. public static void Use(Func<RequestDelegate,RequestDelegate> middleware)
  50. {
  51. _mycomponents.Add(middleware);
  52. }
  53. }
  54. }

  dotnet run后效果如下,整个模拟过程结束,是不是很简单呢。

  

  以上代码大部分是截图,截图看起来更加顺眼,虽然不方便复制,如果你想看完整代码可以访问我的GitHub地址

希望以上分享对你有帮助,我是IT人张飞洪,入行10年有余,人不堪其忧,吾不改其乐,谢谢您关注

4.5管道实现机制和模拟构建管道「深入浅出ASP.NET Core系列」的更多相关文章

  1. 4.4管道和中间件介绍「深入浅出ASP.NET Core系列」

    希望给你3-5分钟的碎片化学习,可能是坐地铁.等公交,积少成多,水滴石穿,谢谢关注. 管道流 我们知道一个管道可以有一个或多个中间件,而中间件的职责是根据HttpContext处理HTTP请求,然后往 ...

  2. asp.net core系列 60 Ocelot 构建服务认证示例

    一.概述 在Ocelot中,为了保护下游api资源,用户访问时需要进行认证鉴权,这需要在Ocelot 网关中添加认证服务.添加认证后,ReRoutes路由会进行身份验证,并使用Ocelot的基于声明的 ...

  3. asp.net core系列 59 Ocelot 构建基础项目示例

    一.入门概述 从这篇开始探讨Ocelot,Ocelot是一个.NET API网关,仅适用于.NET Core,用于.NET面向微服务/服务的架构中.当客户端(web站点.ios. app 等)访问we ...

  4. asp.net core系列 61 Ocelot 构建服务发现简单示例

    一.概述 Ocelot允许指定服务发现提供程序,如Consul或Eureka. 这二个中间件是用来实现:服务治理或秒服务发现,服务发现查找Ocelot正在转发请求的下游服务的主机和端口.目前Ocelo ...

  5. NOIP模拟测试17「入阵曲&#183;将军令&#183;星空」

    入阵曲 题解 应用了一种美妙移项思想, 我们先考虑在一维上的做法 维护前缀和$(sum[r]-sum[l-1])\%k==0$可以转化为 $sum[r]\% k==sum[l-1]\%k$开个桶维护一 ...

  6. NOIP模拟测试14「旋转子段·走格子·柱状图」

    旋转子段 连60分都没想,考试一直肝t3,t2,没想到t1最简单 我一直以为t1很难,看了题解发现也就那样 题解 性质1 一个包含a[i]旋转区间值域范围最多为min(a[i],i)----max(a ...

  7. NOIP模拟测试11「string&#183;matrix&#183;big」

    打的big出了点小问题,maxx初值我设的0然后少了10分 第二题暴力打炸 第一题剪了一些没用的枝依然40分 总分70 这是一次失败的考试 string 想到和序列那个题很像,但我没做序列,考场回忆学 ...

  8. NOIP模拟测试5「星际旅行·砍树·超级树」

    星际旅行 0分 瞬间爆炸. 考试的时候觉得这个题怎么这么难, 打个dp,可以被儿子贡献,可以被父亲贡献,还有自环,叶子节点连边可以贡献,非叶子也可以贡献,自环可以跑一回,自环可以跑两回, 关键是同一子 ...

  9. ASP.NET Core 2.0 : 八.图说管道

    本文通过一张GIF动图来继续聊一下ASP.NET Core的请求处理管道,从管道的配置.构建以及请求处理流程等方面做一下详细的研究.(ASP.NET Core系列目录) 一.概述 上文说到,请求是经过 ...

随机推荐

  1. bzoj [Noi2002]Savage 扩展欧几里得

    枚举m,n^2判断 对于野人i,j,(H[i]+x*S[i])%m==(H[j]+x*S[j])%m,且x<=O[i]&&x<=O[j],他们才有可能相遇 化简得:(S[i ...

  2. BZOJ_[usaco2007 Nov]relays 奶牛接力跑_离散化+倍增弗洛伊德

    BZOJ_[usaco2007 Nov]relays 奶牛接力跑_离散化+倍增弗洛伊德 Description FJ的N(2 <= N <= 1,000,000)头奶牛选择了接力跑作为她们 ...

  3. 使用FileUpload实现Servlet的文件上传

    简介 FileUpload 是 Apache commons下面的一个子项目,用来实现Java环境下的文件上传功能. FileUpload链接 FileUpload 是基于Apache的Commons ...

  4. #利用openCV裁脸

    #利用openCV裁脸import cv2 def draw_rects(img, rects): for x, y, w, h in rects: cv2.rectangle(img, (x, y) ...

  5. 大白话5分钟带你走进人工智能-第三节最大似然推导mse损失函数(深度解析最小二乘来源)(1)

                                                    第三节最大似然推导mse损失函数(深度解析最小二乘来源)        在第二节中,我们介绍了高斯分布的 ...

  6. 使用Java实现二叉树的添加,删除,获取以及遍历

    一段来自百度百科的对二叉树的解释: 在计算机科学中,二叉树是每个结点最多有两个子树的树结构.通常子树被称作“左子树”(left subtree)和“右子树”(right subtree).二叉树常被用 ...

  7. OSI七层协议与TCP连接

    概述 为了追求效率,我们写代码,不可能去关注底层知识,但往往到出了问题,或者性能调优.我们就会速手无策,仔细为自己查缺补漏,总结知识点. 网络协议 互联网的本质就是一系列的网络协议,让不同计算机能够互 ...

  8. 对SVN的落地与实践总结

    现今最为流行的Git是管理很几套很成熟的分支管理策略.而SVN确实也有,但结合现公司的实际场景还是做了些调整和变动. 一.分支命名规则 所有分支命名采用小写字母 + 数字 + 特殊符号 组成 项目分支 ...

  9. Java并发编程面试题 Top 50 整理版

    本文在 Java线程面试题 Top 50的基础上,对部分答案进行进行了整理和补充,问题答案主要来自<Java编程思想(第四版)>,<Java并发编程实战>和一些优秀的博客,当然 ...

  10. 递归一个List<T>,可自己根据需要改造为通用型。

    /// <summary> /// 递归一个List<ProvinceOrg> /// </summary> /// <returns></ret ...