asp.net core中间件实现

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

namespace src
{
    public class Program
    {
        /// <summary>
        /// AOP的经典场景
        /// </summary>
        /// <param name="args"></param>
        /// <returns></returns>
        public static async Task Main(string[] args)
        {
            IApplicationBuilder app = new ApplicationBuilder();

            //这个方法做了:
            //参数传入一个 Func<NetworkContext, NetworkRequestDelegate, Task>类型的逻辑块
            //将这个逻辑块注入到Func<NetworkRequestDelegate, NetworkRequestDelegate>输出的NetworkRequestDelegate中,注入前先执行了输入的NetworkRequestDelegate的逻辑块
            //将最终已实例化的Func<NetworkRequestDelegate, NetworkRequestDelegate>通过非扩展的Use方法添加到IList<Func<NetworkRequestDelegate, NetworkRequestDelegate>> 集合
            //简单的说,每使用一次Use就会在IList<Func<NetworkRequestDelegate, NetworkRequestDelegate>> 集合中添加一个item,
            //其这个item完成了对中间件的组装:在输出NetworkRequestDelegate中先执行输入的NetworkRequestDelegate,再执行了app.Use输入的逻辑块。这个输出的NetworkRequestDelegate是整个框架的核心
            //如后续有疑问,可以跟着客户端调用的思维去理解
            app.Use(async (context, next) =>
            {
                context.SayHello();
                await next.Invoke();
            });

            app.Use(async (context, next) =>
            {
                context.Say("你好,Simon");
                await next.Invoke();
            });

            //Build时其实就是针对已经组装好的中间件集合进行嵌套调用,类似俄罗斯套娃,
            //需要注意的是,套的顺序是从里往外套,按添加的顺序反过来执行.
            //返回一个最终的NetworkRequestDelegate实例
            var _task = app.Build();

            var context = new NetworkContext();
            var context1 = new NetworkContext();

            //执行NetworkRequestDelegate就会执行整个处理管道中的逻辑
            await _task(context);

            await _task(context1);
        }
    }

    public class ApplicationBuilder : IApplicationBuilder
    {
        private readonly IList<Func<NetworkRequestDelegate, NetworkRequestDelegate>> _middlewares = new List<Func<NetworkRequestDelegate, NetworkRequestDelegate>>();
        public NetworkRequestDelegate Build()
        {
            //初始话的NetworkRequestDelegate就是已经完成的task
            NetworkRequestDelegate app = context =>
            {
                return Task.CompletedTask;
            };

            for (var c = _middlewares.Count - 1; c >= 0; c--)
            {
                //每循环一次就是执行了<Func<NetworkRequestDelegate, NetworkRequestDelegate>实例化的代码一次
                //next =>
                //{
                //    return context =>
                //    {
                //        Func<Task> simpleNext = () => next(context);
                //        return middleware(context, simpleNext);
                //    };
                //}
                //传入的app是作为next传入,这也是为何需要将中间件集合从尾部开始遍历的原因
                app = _middlewares[c](app);
            }

            return app;
        }

        public IApplicationBuilder New()
        {
            return new ApplicationBuilder();
        }

        public IApplicationBuilder Use(Func<NetworkRequestDelegate, NetworkRequestDelegate> middleware)
        {
            _middlewares.Add(middleware);
            return this;
        }
    }

    public interface IApplicationBuilder
    {
        IApplicationBuilder Use(Func<NetworkRequestDelegate, NetworkRequestDelegate> middleware);

        NetworkRequestDelegate Build();

        IApplicationBuilder New();

    }

    public class NetworkContext
    {
        private Guid _id;

        public NetworkContext()
        {
            _id = Guid.NewGuid();
        }

        public void SayHello()
        {
            Console.WriteLine($"{_id} say hello.");
        }

        public void Say(string msg)
        {
            Console.WriteLine($"{_id} say {msg}");
        }
    }

    public delegate Task NetworkRequestDelegate(NetworkContext context);

    public static class UseExtensions
    {
        public static IApplicationBuilder Use(this IApplicationBuilder app, Func<NetworkContext, Func<Task>, Task> middleware)
        {
            //实例化Func<NetworkRequestDelegate, NetworkRequestDelegate>,并将其添加到IList<Func<NetworkRequestDelegate, NetworkRequestDelegate>>
            return app.Use(next =>
            {
                //返回实例化输出的NetworkRequestDelegate,它首先执行了next的逻辑,然后执行了middleware的逻辑
                return context =>
                {
                    Func<Task> simpleNext = () => next(context);
                    return middleware(context, simpleNext);
                };
            });
        }

        public static IApplicationBuilder Use(this IApplicationBuilder app, Func<NetworkContext, NetworkRequestDelegate, Task> middleware)
        {
            return app.Use(next => context => middleware(context, next));
        }

    }

    public static class RunExtensions
    {
        public static void Run(this IApplicationBuilder app, NetworkRequestDelegate handler)
        {
            if (app == null)
            {
                throw new ArgumentNullException(nameof(app));
            }

            if (handler == null)
            {
                throw new ArgumentNullException(nameof(handler));
            }

            app.Use(_ => handler);
        }
    }
}

面向AOP的经典案例,特此记录. 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值