首页 > 作文

详解Asp.net 5中的ApplicationBuilder

更新时间:2023-04-04 14:19:10 阅读: 评论:0

applicationbuilder(iapplicationbuilder接口),是owin的基础,而且里面都是代理、代理的代理,各种lambda表达式,估计要看这部分代码,很多人得头昏脑涨。今天就对个类以及几个扩展方法进行讲解。

按惯例先贴代码(这是我修改后的,将接口继承去掉了、httpcontext类修改成自己的myhttpcontext类)

public class applicationbuilder    {        private readonly ilist<func<requestdelegate, requestdelegate>> _components = new list<func<requestdelegate, requestdelegate>>();        public applicationbuilder() { }        private applicationbuilder(applicationbuilder builder)        {        }        public applicationbuilder u(func<requestdelegate, requestdelegate> middleware)        {            _components.add(middleware);            return this;        }        public applicationbuilder new()        {            return new applicationbuilder(this);        }        public requestdelegate build()        {            requestdelegate app = context =>            {                context.statuscode = "404";                system.console.writeline("404");         文学摘抄       return task.fromresult(0);            };            foreach (var component in _components.rever())            {                app = component(app);            }            return app;        }    }

requestdelegate的定义如下:

public delegate task requestdelegate(myhttpcontext context);

从applicationbuilder的源代码中我们可以关注3个点:_components、u方法、build方法。

_components是也一个列表(ilist)对象,不过里面类型有点特殊——是以代理requestdelegate为参数、代理requestdelegate为返回值的一个代理。这里用代理说有点别嘴,可以把代理叫做函数,就是里面的类型是一个函数,这个函数的参数也是函数,返回值也是函数。u方法,就是在上面的列表对象后面添加一条新记录。build方法就是将_components数组按照反向顺序,制作成一个链式结构(有点类似链表的感觉)。下面用俩幅图说明下:

build之前

build之后

我们还可以从代码中看到item1的参数给的是“404”,而返回结果是requestdelegate类型。也就是说这个返回类似于voidrequestdelegate(myhttpcontext context)。如果系统给我们一个context变量,那么这个管道就可以从头到尾的跑下去了。而事实上在asp.net5中,这个管道就是用于替代传统的ihttpmodule的(可能不准确),那现在问题就来了,item1的参数是这个管道的第一环还是最后一环呢?从图形来看应该是第一环,但是事实上这是一个误解。因为箭头两面一个是参数,一个是执行体(参数是一个方法,会在执行体内调用执行)。在执行体内,可能在开始就执行参数的内容,之后执行具体的内容;也可以是先执行具体内容,之后执行参数,最后在执行一部分具体内容;还可以先执行具体内容,之后参数;还可能无视参数,直接直接自己的内容,那么之前的参数就会被忽略。也就是说无所谓顺序,404可能是管道的第一环,也可能是最后一环,也可能是中间环节,还可能压根就不执行。这个和item1、item2等内容具体的写法有关系。(虽然也是链式结构是不是和链表感觉不一样)

是不是感觉太零活了,源码还对applicationbuilder做了俩个扩展方法,代码整理如下:

public static class runextensions    {        public static applicationbuilder u(this applicationbuilder app, func<myhttpcontext, func<task>, task> middleware)        {            return app.u(next =>            {                return context =>                {                    func<task> simplenext = () => next(context);                    return middleware(context, simplenext);                };            });        }        public static void run(this applicationbuilder app, requestdelegate handler)        {            if (app == null)            {                throw new argumentnullexception("why?");            }            if (handler == null)            {                throw new argumentnullexception("how?");            }            app.u(_ => handler);        }    }

首先说u方法,改方法是对之前u方法的一个更改。将传入的参数更改为func<myhttpcontext, func<task>, task>。这样做有什么好处?之前的func<requestdelegate, requestdelegate>对象并不能给人清楚的明了的感觉,而func<myhttpcontext, func<task>, task>就非常明确了。传入的参数:myhttpcontext就是context对象,func<task>就是next的执行体。返回值是一个task(类似于void)。一目了然。

再说run方法,显而易见,run方法只执行自己的内容,并没有执行参数体。所以链式结构的在其前的都会被舍弃,不会被执行。

最后把自己的测试例子贴出来,供大家参考

示例1:

static void main(string[] args)        {            myhttpcontext context = new myhttpcontext() { statuscode = "a" };            func<myhttpcontext, func<task>, task> middleware =                (x, y) => { context.statuscode += "c"; system.console.writeline(context.statuscode); return y(); };            func<myhttpcontext, func<task>, task> middleware2 =              (x, y) => { context.statuscode += "end1"; system.console.writeline(context.statuscode); return task.fromresult(0); };            applicationbuilder builder = new applicationbuilder();            builder.u(                next =>                {                    return (myhttpcontext o) =>                    {                        o.st书记述职述廉报告atuscode += "b";                        system.console.writeline(context.statuscode);                        next(o);                        return task.fromresult(0);                    };          国歌叫什么名字      }            );            builder.u(middleware);            //builder.u(middleware2);            //builder.u(middleware);            //builder.run(o => { o.statuscode += "end2"; return task.fromresult(0); });            builder.build().invoke(context);            system.console.readline();        }

执行结果:

示例2:

static void main(string[] args)        {            myhttpcontext context = new myhttpcontext() { statuscode = "a" };            func<myhttpcontext, func<task>, task> middleware =                (x, y) => { context.statuscode += "c"; system.console.writeline(context.statuscode); return y(); };            func<myhttpcontext, func<task>, task> middleware2 =              (x, y) => { context.statuscode += "end1"; system.console.writeline(context.statuscode); return task.fromresult(0); };            applicationbuilder builder = new applicationbuilder();            builder.u(                next =>                {                    return (myhttpcontext o) =>                    {                        o.statuscode += "b";                        system.console.writeline(context.statuscode);                        next(o)自称是什么意思;                        return task.fromresult(0);                    };                }            );            builder.u(middleware);            builder.u(middleware2);            //builder.u(middleware);            //builder.run(o => { o.statuscode += "end2"; system.console.writeline(context.statuscode); return task.fromresult(0); });            builder.build().invoke(context);            system.console.readline();        }

执行结果:

示例3:

static void main(string[] args)        {            myhttpcontext context = new myhttpcontext() { statuscode = "a" };            func<myhttpcontext, func<task>, task> middleware =                (x, y) => { context.statuscode += "c"; system.console.writeline(context.statuscode); return y(); };            func<myhttpcontext, func<task>, task> middleware2 =              (x, y) => { context.statuscode += "end1"; system.console.writeline(context.statuscode); return task.fromresult(0); };            ap临江仙苏轼plicationbuilder builder = new applicationbuilder();            builder.u(                next =>                {                    return (myhttpcontext o) =>                    {                        o.statuscode += "b";                        system.console.writeline(context.statuscode);                        next(o);                        return task.fromresult(0);                    };                }            );            builder.u(middleware);            //builder.u(middleware2);            //builder.u(middleware);            builder.run(o => { o.statuscode += "end2"; system.console.writeline(context.statuscode); return task.fromresult(0); });            builder.build().invoke(context);            system.console.readline();        }

执行结果:

到此这篇关于详解asp.net 5中的applicationbuilder的文章就介绍到这了。希望对大家的学习有所帮助,也希望大家多多支持www.887551.com。

本文发布于:2023-04-04 14:19:08,感谢您对本站的认可!

本文链接:https://www.wtabcd.cn/fanwen/zuowen/ab4ed001400ad4092d3daa7dfae37a99.html

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。

本文word下载地址:详解Asp.net 5中的ApplicationBuilder.doc

本文 PDF 下载地址:详解Asp.net 5中的ApplicationBuilder.pdf

标签:参数   方法   自己的   链式
相关文章
留言与评论(共有 0 条评论)
   
验证码:
Copyright ©2019-2022 Comsenz Inc.Powered by © 专利检索| 网站地图