zoukankan      html  css  js  c++  java
  • asp.net core 中间件粗解

    中间件

    中间件在asp.net core中非常重要,它用来处理httpcontext。而httpcontext封装了请求和响应。也就是说,中间件是用来处理请求和响应的。

    本质上,中间件被封装到了IApplicationBuilder这个接口中,他的实现类是ApplicationBuilder。源码在github:https://github.com/aspnet/HttpAbstractions

    ApplicationBuilder有两个方法和一个字段比较重要:

    private readonly IList<Func<RequestDelegate, RequestDelegate>> _components = new List<Func<RequestDelegate, RequestDelegate>>();
     public IApplicationBuilder Use(Func<RequestDelegate, RequestDelegate> middleware)
            {
                _components.Add(middleware);
                return this;
            }
    public RequestDelegate Build()
            {
                RequestDelegate app = context =>
                {
                    context.Response.StatusCode = 404;
                    return Task.CompletedTask;
                };
    
                foreach (var component in _components.Reverse())
                {
                    app = component(app);
                }
    
                return app;
            }

    这个_components字段就是中间件的一个集合,在Startup类中,通过app.Use()和Run()还有Use***MIddleware等扩展方法,在背后是通过ApplicationBuilder这个类的本身的Use方法来转换成一个Func<RequestDelegate,RequestDelegate>,然后添加到_components这个字段上的。比如说我们会在Startup类中写这样的中间件(毫无意义的代码,纯粹是为了演示):

     app.Use(async (context, next) =>
                {
                    await context.Response.WriteAsync("when a 
    ");
                    await next();
                    await context.Response.WriteAsync("after a 
    ");
                });

    这段代码中,app.Use是一个扩展方法,给这个方法传入了一个Func<HttpContext,Func<Task>,Task>,而这个扩展方法如下:

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

    在这个扩展方法的内部,还是最终调用了ApplicationBuilder的Use方法(不是扩展方法),这个方法在内部通过Func<Task> simpleNext = () => next(context);这段代码把传入的Func<HttpContext, Func<Task>, Task>中的Func<Task>参数转化成了内部的调用(有一些拗口,意思就是转化了一下,以便这个中间件能够继续调用HttpContext)最终,才调用传入的middleware。然后,将这个委托返回,最终,添加到了_component字段上面。

  • 相关阅读:
    BZOJ3171: [Tjoi2013]循环格
    Luogu P1850 换教室(期望dp)
    Luogu P3825 [NOI2017]游戏(2-SAT)
    Luogu P3007 [USACO11JAN]大陆议会The Continental Cowngress
    Luogu P2272 [ZJOI2007]最大半连通子图(Tarjan+dp)
    Luogu P3209 [HNOI2010]平面图判定(2-SAT)
    Luogu P4171 [JSOI2010]满汉全席(2-SAT)
    Luogu P4782 【模板】2-SAT 问题(2-SAT)
    Luogu P2845 [USACO15DEC]Switching on the Lights 开关灯(bfs)
    Luogu P4933 大师(dp)
  • 原文地址:https://www.cnblogs.com/pangjianxin/p/9833676.html
Copyright © 2011-2022 走看看