4.5管道实现机制和模拟构建管道「深刻浅出ASP.NET Core系列」

但愿给你3-5分钟的碎片化学习,多是坐地铁、等公交,聚沙成塔,水滴石穿,谢谢关注。git

管道实现机制

要了解管道的实现机制,咱们必需要深刻框架的源码,幸好微软开源了,咱们能够访问GitHub的地址来下载源码。github

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

   

Use方法

  

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

  

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

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

  

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

  

Build方法

   Use完了以后,接下来作什么呢?咱们看下Build实现代码。spa

  

  这里对RequestDelegate集合进行反转,而后逐一调用执行,因此app会被最后一个执行。最后只返回一个RequestDelegate code

模拟构建管道

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

  

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

  

  RequestDelegate.cs定义一个委托

  

  由于是模拟,因此咱们这里使用控制台来测试,dotnet new console --name iConsole

  咱们在Program.cs实现核心代码以下:

using System;
using System.Collections.Generic;
using System.Threading.Tasks;

namespace iConsole
{
    class Program
    {
        private static readonly IList<Func<RequestDelegate, RequestDelegate>> _mycomponents = 
            new List<Func<RequestDelegate, RequestDelegate>>();

        static void Main(string[] args)
        {
            //如下是Lambada表达式的简写
            Use(next =>
            {
                return context =>
                {
                    Console.WriteLine("PipeLine 1……");
                    return next.Invoke(context);
                };
            });

            Use(next =>
            {
                return context =>
                {
                    Console.WriteLine("PipeLine 2……");
                    return next.Invoke(context);
                };
            });

            RequestDelegate PipeLine_end = context =>
            {
                Console.WriteLine("PipeLine_end……");
                return Task.CompletedTask;
            };

            foreach (var component in _mycomponents)
            {
                PipeLine_end = component(PipeLine_end);
            }

            PipeLine_end.Invoke(new HttpContext());

            Console.ReadLine();
        }

        public static void Use(Func<RequestDelegate,RequestDelegate> middleware)
        {
            _mycomponents.Add(middleware);
        }
    }
}

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

  

  以上代码大部分是截图,截图看起来更加顺眼,虽然不方便复制,若是你想看完整代码能够访问个人GitHub地址

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

相关文章
相关标签/搜索