亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb

首頁 > 學院 > 開發設計 > 正文

[Asp.net5]ApplicationBuilder詳解

2019-11-14 14:32:08
字體:
來源:轉載
供稿:網友

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 Use(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.Reverse())            {                app = component(app);            }            return app;        }    }
View Code

 RequestDelegate的定義如下:

public delegate Task RequestDelegate(MyHttpContext context);

從ApplicationBuilder的源代碼中我們可以關注3個點:_components、Use方法、Build方法。

  • _components是也一個列表(IList)對象,不過里面類型有點特殊——是以代理RequestDelegate為參數、代理RequestDelegate為返回值的一個代理。這里用代理說有點別嘴,可以把代理叫做函數,就是里面的類型是一個函數,這個函數的參數也是函數,返回值也是函數。
  • Use方法,就是在上面的列表對象后面添加一條新記錄。
  • Build方法就是將_components數組按照反向順序,制作成一個鏈式結構(有點類似鏈表的感覺)。下面用倆幅圖說明下:

  Build之前

 

  Build之后

  我們還可以從代碼中看到Item1的參數給的是“404”,而返回結果是RequestDelegate類型。也就是說這個返回類似于void RequestDelegate(MyHttpContext context)。如果系統給我們一個context變量,那么這個管道就可以從頭到尾的跑下去了。而事實上在asp.net5中,這個管道就是用于替代傳統的IHttpModule的(可能不準確),那現在問題就來了,Item1的參數是這個管道的第一環還是最后一環呢?從圖形來看應該是第一環,但是事實上這是一個誤解。因為箭頭兩面一個是參數,一個是執行體(參數是一個方法,會在執行體內調用執行)。在執行體內,可能在開始就執行參數的內容,之后執行具體的內容;也可以是先執行具體內容,之后執行參數,最后在執行一部分具體內容;還可以先執行具體內容,之后參數;還可能無視參數,直接直接自己的內容,那么之前的參數就會被忽略。也就是說無所謂順序,404可能是管道的第一環,也可能是最后一環,也可能是中間環節,還可能壓根就不執行。這個和Item1、Item2等內容具體的寫法有關系。(雖然也是鏈式結構是不是和鏈表感覺不一樣

  是不是感覺太零活了,源碼還對ApplicationBuilder做了倆個擴展方法,代碼整理如下:

   public static class RunExtensions    {        public static ApplicationBuilder Use(this ApplicationBuilder app, Func<MyHttpContext, Func<Task>, Task> middleware)        {            return app.Use(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.Use(_ => handler);        }    }
View Code

   首先說Use方法,改方法是對之前Use方法的一個更改。將傳入的參數更改為 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.Use(                next =>                {                    return (MyHttpContext o) =>                    {                        o.StatusCode += "B";                        System.Console.WriteLine(context.StatusCode);                        next(o);                        return Task.FromResult(0);                    };                }            );            builder.Use(middleware);            //builder.Use(middleware2);            //builder.Use(middleware);            //builder.Run(o => { o.StatusCode += "End2"; return Task.FromResult(0); });            builder.Build().Invoke(context);            System.Console.ReadLine();        }
View Code

執行結果:

示例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.Use(                next =>                {                    return (MyHttpContext o) =>                    {                        o.StatusCode += "B";                        System.Console.WriteLine(context.StatusCode);                        next(o);                        return Task.FromResult(0);                    };                }            );            builder.Use(middleware);            builder.Use(middleware2);            //builder.Use(middleware);            //builder.Run(o => { o.StatusCode += "End2"; System.Console.WriteLine(context.StatusCode); return Task.FromResult(0); });            builder.Build().Invoke(context);            System.Console.ReadLine();        }
View Code

執行結果:

示例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); };            ApplicationBuilder builder = new ApplicationBuilder();            builder.Use(                next =>                {                    return (MyHttpContext o) =>                    {                        o.StatusCode += "B";                        System.Console.WriteLine(context.StatusCode);                        next(o);                        return Task.FromResult(0);                    };                }            );            builder.Use(middleware);            //builder.Use(middleware2);            //builder.Use(middleware);            builder.Run(o => { o.StatusCode += "End2"; System.Console.WriteLine(context.StatusCode); return Task.FromResult(0); });            builder.Build().Invoke(context);            System.Console.ReadLine();        }
View Code

執行結果:

 


發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb
亚洲电影免费观看高清完整版在线观看| 91日韩在线播放| 日韩在线观看你懂的| 91日本视频在线| 国内伊人久久久久久网站视频| 色综久久综合桃花网| 最近2019中文字幕第三页视频| 国产脚交av在线一区二区| 亚洲黄色www| 国产91在线播放精品91| 欧美性xxxxx极品| 国产精品国产福利国产秒拍| 91chinesevideo永久地址| 日韩成人在线网站| 伦伦影院午夜日韩欧美限制| 亚洲欧美日韩精品久久| 91久久精品在线| 伊人久久男人天堂| 亚洲激情视频网站| 欧美日韩亚洲91| 久久天天躁狠狠躁老女人| **欧美日韩vr在线| 亚洲综合国产精品| 欧美性视频在线| 91在线高清免费观看| 国产一区二区黑人欧美xxxx| 成人激情视频在线播放| 亚洲国产精品系列| 国产精品网站入口| 国产精品成人一区| 亚洲第一免费网站| 日本精品一区二区三区在线播放视频| 国产香蕉精品视频一区二区三区| 日本精品va在线观看| 国产成人精品视频| 亚洲人成毛片在线播放| 久久精品国产清自在天天线| 久久精品国产成人| 在线观看视频亚洲| 久久久久久久久久国产| 中文字幕一区日韩电影| 日韩美女毛茸茸| 国色天香2019中文字幕在线观看| 在线成人激情视频| 亚洲国产一区自拍| 精品精品国产国产自在线| 91精品国产91久久久| 95av在线视频| 91成人天堂久久成人| 日韩中文在线中文网三级| 国产mv免费观看入口亚洲| 欧美性猛交xxxxx免费看| 亚洲精品一区二区三区婷婷月| 日韩精品免费观看| 精品偷拍各种wc美女嘘嘘| 国产一区二区三区久久精品| 成人网在线视频| 欧美高清在线播放| 一区二区三区视频免费| 亚洲精品91美女久久久久久久| 亚洲精品国产综合久久| 91亚洲国产成人久久精品网站| 久久久久中文字幕2018| 亚洲色图17p| 亚洲一二在线观看| 91av在线影院| 91精品国产综合久久香蕉最新版| 欧美最猛性xxxxx(亚洲精品)| 国产91成人在在线播放| 亚洲一区二区久久久久久| 97超碰国产精品女人人人爽| 亚洲精品二三区| 中文字幕日韩av电影| 久久精品国产视频| 51色欧美片视频在线观看| 亚洲成avwww人| 亚洲精品国产精品自产a区红杏吧| 国产精品久久一区主播| 97碰碰碰免费色视频| 欧美重口另类videos人妖| yellow中文字幕久久| 欧美丰满片xxx777| 国产成人高清激情视频在线观看| 久久精品99久久香蕉国产色戒| 日韩av毛片网| 日韩av电影在线免费播放| 欧美成人自拍视频| 色噜噜狠狠色综合网图区| 欧美一区视频在线| 日韩专区中文字幕| 亚洲va欧美va国产综合剧情| 久久免费观看视频| 久久久久久久久久国产精品| 亚洲精品资源在线| 国产成人免费91av在线| 亚洲人永久免费| 国产精品高清免费在线观看| 亚洲人午夜精品免费| 国产精品久久电影观看| 成人有码在线播放| 国产区亚洲区欧美区| 国产欧美最新羞羞视频在线观看| 国产一区二区三区网站| 欧美色视频日本高清在线观看| 成人妇女淫片aaaa视频| 欧美乱大交xxxxx| 国产精品亚洲一区二区三区| 日本成人激情视频| 亚洲精品免费网站| 欧美大尺度激情区在线播放| 成人黄色在线免费| 久久网福利资源网站| 亚洲成人网在线观看| 欧美裸体xxxx极品少妇| 亚洲网站在线看| 国产精品久久久久国产a级| 欧美极品少妇xxxxx| 久久精品国产一区| 国产精品视频自拍| 亚洲伊人成综合成人网| 国产精品丝袜久久久久久高清| www.99久久热国产日韩欧美.com| 欧美wwwxxxx| 日韩免费在线电影| 久久91亚洲精品中文字幕| 欧美一级视频一区二区| 久久久久中文字幕| 亚洲一区二区免费| 欧洲成人在线观看| 亚洲精品国产综合区久久久久久久| 国产精国产精品| 亚洲跨种族黑人xxx| 一区二区av在线| 日韩在线视频播放| 国产精品久久久久高潮| 尤物99国产成人精品视频| 亚洲国产精品专区久久| 日韩欧美中文字幕在线观看| 欧美日韩国产中文精品字幕自在自线| 亚洲精品国产免费| 欧美激情免费在线| 亚洲爱爱爱爱爱| 欧美激情亚洲视频| 日韩欧美亚洲国产一区| 国产精品美女www爽爽爽视频| 久久久久久久久电影| 91视频免费在线| 欧美黑人极品猛少妇色xxxxx| 亚洲激情电影中文字幕| 中文字幕v亚洲ⅴv天堂| 日韩有码视频在线| 国产视频一区在线| 青青a在线精品免费观看| 午夜欧美不卡精品aaaaa| 久久国产精品久久久| 亚洲国产日韩欧美在线动漫| 欧美日韩国产中字| 国产精品日韩精品| 91福利视频在线观看| 亚洲精品免费网站| 69久久夜色精品国产69乱青草| 国产精品久久国产精品99gif| 91国内在线视频| 91久久久久久国产精品|