.net core 2.0学习记录(四):Middleware使用以及模拟构建Middleware(RequestDelegate)管道

    .net Core中没有继续沿用以前asp.net中的管道事件,而是开发了一个新的管道(Middleware):

复制代码
    public class MiddlewareDemo
    {
        private readonly RequestDelegate _next;

        public MiddlewareDemo(RequestDelegate next)
        {
            _next = next;
        }

        public Task Invoke(HttpContext httpContext)
        {
            //可以在此处写一些需要的代码
            return _next.Invoke(httpContext);
        }
    }
复制代码

 在Startup的Configure方法中用UseMiddleware方法添加到管道中去

  app.UseMiddleware<MiddlewareDemo>();

如果将_next.Invoke(httpContext)改成Task.CompletedTask那么后续添加的Middleware都不会执行了

        public Task Invoke(HttpContext httpContext)
        {
            return Task.CompletedTask;
            //return _next.Invoke(httpContext);
        }

通过查看UseMiddleware方法源代码,发现其实际调用的是IApplicationBuilder的Use方法

 

模拟构建Middleware(RequestDelegate)管道

方便演示我们就创建控制台项目,代码如下:

public delegate Task RequestDelegate(Context context);
    public class Context
    {

    }
复制代码
    class Program
    {
        static List<Func<RequestDelegate, RequestDelegate>> list = new List<Func<RequestDelegate, RequestDelegate>>();
        static void Main(string[] args)
        {
            Use(next =>
            {
                return context =>
                {
                    Console.WriteLine("111");
                    return next.Invoke(context);
                };
            });

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

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

            Build();

            Console.Read();
        }

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

        static void Build()
        {
            RequestDelegate endReq = (context) =>
            {
                Console.WriteLine("end");
                return Task.CompletedTask;
            };
            list.Reverse();  //不反转的话最后添加的会先执行
            foreach (var middleware in list)
            {
                endReq = middleware.Invoke(endReq);
            }
       //执行到此处endReq是第一个添加到list集合中的Middleware endReq(
new Context()); } }
复制代码

运行结果:

如果在某一个Use方法中不执行next.Invoke(context),那么后续使用Use方法添加的都不会执行了,改成如下:

复制代码
            Use(next =>
            {
                return context =>
                {
                    Console.WriteLine("222");
                    return Task.CompletedTask;
                    //return next.Invoke(context);
                };
            });
复制代码

 

总结:

这样的一种模式扩展性比较好,比如一个项目中要使用MVC则写app.UseMvc来添加进去,使用Session,则用app.UseSession()。

Session/Route/Cros等都是使用Middleware来实现的

 

posted @   ZuQing  阅读(829)  评论(5编辑  收藏  举报
编辑推荐:
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 基于Microsoft.Extensions.AI核心库实现RAG应用
· Linux系列:如何用heaptrack跟踪.NET程序的非托管内存泄露
阅读排行:
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· 阿里巴巴 QwQ-32B真的超越了 DeepSeek R-1吗?
· 【译】Visual Studio 中新的强大生产力特性
· 【设计模式】告别冗长if-else语句:使用策略模式优化代码结构
· 10年+ .NET Coder 心语 ── 封装的思维:从隐藏、稳定开始理解其本质意义
点击右上角即可分享
微信分享提示