最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

詳解Asp.net 5中的ApplicationBuilder

 更新時間:2022年01月13日 17:16:34   作者:[水&月]墳  
這篇文章介紹了Asp.net 5中的ApplicationBuilder,文中通過示例代碼介紹的非常詳細。對大家的學(xué)習(xí)或工作具有一定的參考借鑒價值,需要的朋友可以參考下

ApplicationBuilder(IApplicationBuilder接口),是OWIN的基礎(chǔ),而且里面都是代理、代理的代理,各種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;
        }

    }

RequestDelegate的定義如下:

public delegate Task RequestDelegate(MyHttpContext context);

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

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

Build之前

Build之后

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

是不是感覺太零活了,源碼還對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);
        }
    }

首先說Use方法,改方法是對之前Use方法的一個更改。將傳入的參數(shù)更改為Func<MyHttpContext, Func<Task>, Task>。這樣做有什么好處?之前的Func<RequestDelegate, RequestDelegate>對象并不能給人清楚的明了的感覺,而Func<MyHttpContext, Func<Task>, Task>就非常明確了。傳入的參數(shù):MyHttpContext就是Context對象,F(xiàn)unc<Task>就是next的執(zhí)行體。返回值是一個Task(類似于void)。一目了然。

再說Run方法,顯而易見,Run方法只執(zhí)行自己的內(nèi)容,并沒有執(zhí)行參數(shù)體。所以鏈?zhǔn)浇Y(jié)構(gòu)的在其前的都會被舍棄,不會被執(zhí)行。

最后把自己的測試例子貼出來,供大家參考

示例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();
        }

執(zhí)行結(jié)果:

示例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();
        }

執(zhí)行結(jié)果:

示例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();
        }

執(zhí)行結(jié)果:

 到此這篇關(guān)于詳解Asp.net 5中的ApplicationBuilder的文章就介紹到這了。希望對大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。

您可能感興趣的文章:

相關(guān)文章

  • Asp.Net常用函數(shù)

    Asp.Net常用函數(shù)

    Asp.Net常用函數(shù)...
    2007-03-03
  • asp.net Timer的使用方法

    asp.net Timer的使用方法

    使用方法很簡單,對于需要使用asp.net下timer控件的使用是個不錯的例子
    2008-10-10
  • ewebeditor在.net的使用方法

    ewebeditor在.net的使用方法

    ewebeditor在.net的使用方法...
    2006-11-11
  • MSMQ微軟消息隊列詳解

    MSMQ微軟消息隊列詳解

    本文詳細講解了MSMQ微軟消息隊列,文中通過示例代碼介紹的非常詳細。對大家的學(xué)習(xí)或工作具有一定的參考借鑒價值,需要的朋友可以參考下
    2022-01-01
  • ASP.Net Core MVC基礎(chǔ)系列之中間件

    ASP.Net Core MVC基礎(chǔ)系列之中間件

    這篇文章介紹了ASP.Net Core MVC的中間件,對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2022-02-02
  • .Net性能測試框架Crank的使用方法

    .Net性能測試框架Crank的使用方法

    這篇文章介紹了.Net性能測試框架Crank的使用方法。對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2021-11-11
  • 獲取當(dāng)前url

    獲取當(dāng)前url

    獲取當(dāng)前url...
    2006-08-08
  • ASP.NET?Core托管模型CreateDefaultBuilder()方法

    ASP.NET?Core托管模型CreateDefaultBuilder()方法

    這篇文章介紹了ASP.NET?Core托管模型CreateDefaultBuilder()方法,對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2022-02-02
  • Linux下使用Jenkins自動化構(gòu)建.NET?Core應(yīng)用

    Linux下使用Jenkins自動化構(gòu)建.NET?Core應(yīng)用

    這篇文章介紹了Linux下使用Jenkins自動化構(gòu)建.NET?Core應(yīng)用的方法,對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2022-04-04
  • ASP.NET Core MVC中的控制器(Controller)介紹

    ASP.NET Core MVC中的控制器(Controller)介紹

    這篇文章介紹了ASP.NET Core MVC中的控制器(Controller),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2022-04-04

最新評論

含山县| 临邑县| 德州市| 嘉黎县| 四会市| 罗平县| 阿巴嘎旗| 临江市| 吴江市| 平乐县| 屯留县| 陇川县| 邯郸市| 正阳县| 朝阳区| 吴忠市| 镇坪县| 呼伦贝尔市| 铜陵市| 密山市| 通河县| 类乌齐县| 南陵县| 盈江县| 峨边| 延川县| 亳州市| 定日县| 岢岚县| 海安县| 禹城市| 蕲春县| 宜兰市| 平泉县| 遵化市| 山东| 天祝| 宁城县| 漾濞| 陆丰市| 泰和县|