日本不卡不码高清免费观看,久久国产精品久久w女人spa,黄色aa久久,三上悠亚国产精品一区二区三区

您的位置:首頁技術(shù)文章
文章詳情頁

ASP.NET Core自定義中間件的方式詳解

瀏覽:437日期:2022-06-08 13:51:45
目錄
  • 1.委托形式
  • 2.強(qiáng)類型中間件
    • 2.1.定義中間件的依賴
    • 2.2.定義中間件類型
  • 3.基于約定的中間件
    • 3.1.約定規(guī)則
    • 3.2.應(yīng)用實(shí)現(xiàn)
  • 總結(jié)

    ASP.NET Core應(yīng)用本質(zhì)上,其實(shí)就是由若干個(gè)中間件構(gòu)建成的請(qǐng)求處理管道。管道相當(dāng)于一個(gè)故事的框架,而中間件就相當(dāng)于故事中的某些情節(jié)。同一個(gè)故事框架采用不同的情節(jié)拼湊,最終會(huì)體現(xiàn)出不同風(fēng)格的故事。而我們的ASP.NET Core應(yīng)用也正是如此,同一管道采用不同的中間件組合,最終也會(huì)呈現(xiàn)出不同的應(yīng)用形態(tài)。

    從上述的概念種可以看出,中間件在ASP.NET Core應(yīng)用有著舉足輕重的地位。雖然ASP.NET Core為我們提供了一組豐富的內(nèi)置中間件,但有些時(shí)候我們可能會(huì)需要自定義一些中間件,將其穿插到管道中,以便滿足我們特定業(yè)務(wù)場(chǎng)景的需求,所以本文將介紹3種方式來滿足自定義中間件的需求。

    1.委托形式

    在應(yīng)用程序代碼中,我們可以從用于注冊(cè)中間件的Use方法中看出,所謂管道中的中間件其實(shí)就是一種委托類型的對(duì)象,這個(gè)具體的委托對(duì)象體現(xiàn)為“Fun<RequestDelegate,RequestDelegate>”。

    從Fun<RequestDelegate,RequestDelegate>委托的定義可以看出,該委托類型的入?yún)⒑头祷刂刀际且粋€(gè)RequestDelegate委托類型的對(duì)象。RequestDelegate委托類型其實(shí)就是管道在代碼中的體現(xiàn)形式,該委托類型承載很多關(guān)于請(qǐng)求響應(yīng)的重要信息,定義如下:

    public delegate Task RequestDelegate(HttpContext context);

    Fun<RequestDelegate,RequestDelegate>委托中,入?yún)⒌腞equestDelegate對(duì)象表示由上一個(gè)中間件構(gòu)建的管道,返回值的RequestDelegate對(duì)象表示:將當(dāng)前中間件基于上一個(gè)管道處理后生成的新管道。由于中間件體現(xiàn)為一個(gè)Fun<RequestDelegate,RequestDelegate>委托對(duì)象,那么這就代表我們可以定義一個(gè)與該委托具有一致聲明的方法作為自定義中間件的方式。具體的代碼實(shí)現(xiàn)方式如下:

    //創(chuàng)建應(yīng)用var app = WebApplication.Create(args);//轉(zhuǎn)換獲得應(yīng)用建造者IApplicationBuilder appBuilder = app;//注冊(cè)自定義的中間件appBuilder.Use(SayHi);//運(yùn)行應(yīng)用app.Run();//定義為Fun<RequestDelegate,RequestDelegate>類型的方法static RequestDelegate SayHi(RequestDelegate  request)    => httpContext => httpContext.Response.WriteAsync("Hello");

    上面的代碼是在一個(gè)原始的控制臺(tái)程序中編寫的,并且自行進(jìn)行了主機(jī)應(yīng)用的構(gòu)建。在代碼中定義了一個(gè)和Fun<RequestDelegate,RequestDelegate>委托簽名一致的SayHi方法,并以此方法作為中間件進(jìn)行了引用。雖然這是一個(gè)可行的方式,但在實(shí)際開發(fā)的工作場(chǎng)景中,其實(shí)很少會(huì)使用委托形式作為自定義中間件的方式。在此處之所以演示這種形式,主要是為了表面中間件本質(zhì)是一個(gè)委托,并且不管通過什么形式去定義中間件,它最終都會(huì)體現(xiàn)為一個(gè)Fun<RequestDelegate,RequestDelegate>委托對(duì)象。

    2.強(qiáng)類型中間件

    在實(shí)際的開發(fā)過程中,基本上都會(huì)將自定義的中間件定義為一個(gè)具體類型,而對(duì)于使用強(qiáng)類型的中間件而言,則我們定義的中間件類型必須實(shí)現(xiàn)IMiddleware接口。既然通過一個(gè)具體類型來定義中間件,類型在使用上則勢(shì)必會(huì)與其他類型產(chǎn)生依賴關(guān)聯(lián)性,那么對(duì)于中間件類型中依賴服務(wù)的實(shí)例化,框架則要求我們使用依賴注入的方式。接下來我們將通過代碼示例演示如何定義一個(gè)強(qiáng)類型的中間件。

    2.1.定義中間件的依賴

    下面代碼定義的類型是我們預(yù)先為中間件類型定義的依賴項(xiàng),ISeasonTips接口類型的作用主要是,根據(jù)不同月份獲取對(duì)應(yīng)的季節(jié),并輸出對(duì)應(yīng)季節(jié)的注意事項(xiàng),其中SeasonTips類型是接口的默認(rèn)實(shí)現(xiàn)。

    public interface ISeasonTips    {string Prompt(DateTimeOffset time);    }    public class SeasonTips : ISeasonTips    {//根據(jù)不同月份提示季節(jié)注意事項(xiàng)public string Prompt(DateTimeOffset time) => time.Month switch{    var h when h >= 3 && h <= 5 => "春天到了,早晚溫差比較大,要注意別感冒。",    var h when h >= 6 && h <= 8 => "夏天到了,天氣炎熱,要注意別防嗮。",    var h when h >= 9 && h <= 11 => "秋天到了,天氣干燥,要注意多喝水。",    _ => "冬天到了,天氣寒冷,要注意防寒保暖。"}; //END Prompt()      }

    2.2.定義中間件類型

    下面的代碼中,我們定義了一個(gè)名為SeasonMiddleware的中間件類型,并實(shí)現(xiàn)IMiddleware接口。該中間件的處理請(qǐng)求的邏輯在InvokeAsync方法中,該方法調(diào)用其依賴類型的Prompt方法,根據(jù)當(dāng)前時(shí)間獲取當(dāng)前季節(jié)的注意事項(xiàng)進(jìn)行輸出。在該調(diào)用該方法后,我們還對(duì)InvokeAsync的另一個(gè)參數(shù):“RequestDelegate類型的委托對(duì)象”進(jìn)行了調(diào)用,以便執(zhí)行管道中的下一個(gè)中間件。另外,對(duì)于中間件依賴的類型ISeasonTips,我們將其定義在構(gòu)造函數(shù)的參數(shù)列表上,以便依賴注入容器提供相應(yīng)的實(shí)例。

    /// <summary>    /// 強(qiáng)類型中間件    /// </summary>    public class SeasonMiddleware : IMiddleware    {//依賴類型,通過構(gòu)造函數(shù)進(jìn)行依賴注入private readonly ISeasonTips _seasonTips;public SeasonMiddleware(ISeasonTips seasonTips){    _seasonTips = seasonTips;}//調(diào)用依賴的“季節(jié)提示類型”,根據(jù)當(dāng)前時(shí)間獲取當(dāng)前季節(jié)的注意事項(xiàng),并進(jìn)行響應(yīng)輸出public async Task InvokeAsync(HttpContext context, RequestDelegate next){    await context.Response.WriteAsync(_seasonTips.Prompt(DateTimeOffset.Now));    //調(diào)用管道中的下一個(gè)中間件    await next(context);}  // END InvokeAsync()    }  // END Class

    在下面的代碼中我們對(duì)自定義的“強(qiáng)類型中間件”進(jìn)行了應(yīng)用。由于“強(qiáng)類型中間件”的實(shí)例以及依賴都是由依賴注入容器提供的,所以不僅要對(duì)依賴的服務(wù)進(jìn)行注冊(cè),還要對(duì)自身的中間件類型進(jìn)行服務(wù)注冊(cè)。在服務(wù)注冊(cè)之后,我們使用WebApplication對(duì)象的UseMiddleware<SeasonMiddleware>擴(kuò)展方法,將該中間件添加到應(yīng)用程序的請(qǐng)求管道中。由于在該中間件后沒有其他中間件的處理,所以我們通過調(diào)用Run擴(kuò)展方法注冊(cè)了管道末端的中間件,以便結(jié)束當(dāng)前請(qǐng)求,將響應(yīng)輸出到客戶端。

    using dotNet6Demo;//創(chuàng)建“應(yīng)用建造者”var builder = WebApplication.CreateBuilder(args);//服務(wù)注冊(cè)builder.Services.AddSingleton<ISeasonTips, SeasonTips>().AddSingleton<SeasonMiddleware>();//構(gòu)建應(yīng)用var app = builder.Build();//引用強(qiáng)類型中間件app.UseMiddleware<SeasonMiddleware>();//末端的中間件app.Run(async (context) =>{    await context.Response.WriteAsync("請(qǐng)求結(jié)束");});//運(yùn)行應(yīng)用app.Run();

    到目前為止,結(jié)合本示例以上的3個(gè)步驟,啟動(dòng)運(yùn)行程序就可以驗(yàn)證自定義強(qiáng)類型中間件的效果了。

    3.基于約定的中間件

    對(duì)于ASP.NET的開發(fā)者而言,基于約定的編程模式應(yīng)該不會(huì)陌生。例如在ASP.NET MVC框架中,“Action”默認(rèn)查找視圖就有一種基于約定的規(guī)則,即“Action”首先會(huì)在Views目錄中查找與當(dāng)前“Controller”同名的目錄,然后在該目錄中查找與“Action”同名的視圖文件。這種基于約定的設(shè)計(jì)方式,在自定義中間件領(lǐng)域也同樣使用到了,即基于約定的中間件。

    3.1.約定規(guī)則

    基于約定的中間件它不必像強(qiáng)類型中間件那樣,必須實(shí)現(xiàn)IMiddleware接口或繼承某些基類,它只用按照框架約定的方式定義中間件類型即可,具體的約定規(guī)則如下:

    1. 中間件類型必須要定義為一個(gè)公共的、可供外界實(shí)例化的類型,靜態(tài)類型無效;
    2. 構(gòu)造函數(shù)的參數(shù)中必須包含RequestDelegate類型,如果存在依賴類型則也必須包含在構(gòu)造函數(shù)中;

    必須定義InvokeAsync或Invoke方法,方法簽名為:public Task Invoke(HttpContext context);

    對(duì)以上的約定進(jìn)行一個(gè)補(bǔ)充說明:構(gòu)造函數(shù)的參數(shù)列表要包含依賴的類型,是為了依賴注入容器對(duì)依賴類型提供實(shí)例;RequestDelegate參數(shù)具有傳遞性,表示由后續(xù)中間件構(gòu)建的管道,當(dāng)前中間件利用它將請(qǐng)求轉(zhuǎn)交給后續(xù)管道進(jìn)行處理。InvokeAsync或Invoke方法主要是代表中間件在管道中處理請(qǐng)求的邏輯。

    3.2.應(yīng)用實(shí)現(xiàn)

    下面我們?cè)?ldquo;強(qiáng)類型中間件”示例的基礎(chǔ)上,根據(jù)約定規(guī)則將SeasonMiddleware類型改造為“基于約定的中間件”,代碼如下:

    /// <summary>    /// 基于約定的中間件    /// </summary>    public class SeasonMiddleware    {private readonly ISeasonTips _seasonTips;private readonly RequestDelegate _next;public SeasonMiddleware(ISeasonTips seasonTips, RequestDelegate next){    _seasonTips = seasonTips;    _next = next;}//調(diào)用依賴的“季節(jié)提示類型”,根據(jù)當(dāng)前時(shí)間獲取當(dāng)前季節(jié)的注意事項(xiàng),并進(jìn)行響應(yīng)輸出public async Task InvokeAsync(HttpContext context){    await context.Response.WriteAsync(_seasonTips.Prompt(DateTimeOffset.Now));    //調(diào)用管道中的下一個(gè)中間件    await _next(context);}  // END InvokeAsync()    }  // END Class

    在中間件引用方面,“基于約定的中間件”同樣可以使用“app.UseMiddleware<SeasonMiddleware>()”的方式進(jìn)行引用,但是在此我們介紹一種較為常用的方式,就是將自定義中間件的引用方式進(jìn)行封裝,將其作為IApplicationBuilder類型的擴(kuò)展方法來使用,擴(kuò)展方法定義的代碼如下:

    public static class SeasonMiddlewareExtensions    {public static IApplicationBuilder UseSeason(this IApplicationBuilder builder){    return builder.UseMiddleware<SeasonMiddleware>();}    }

    接下來在示例應(yīng)用方面,將其調(diào)整為使用“基于約定中間件”的形式,并使用擴(kuò)展方法引用中間件。

    using dotNet6Demo;//創(chuàng)建“應(yīng)用建造者”var builder = WebApplication.CreateBuilder(args);//服務(wù)注冊(cè)builder.Services.AddSingleton<ISeasonTips, SeasonTips>();//構(gòu)建應(yīng)用var app = builder.Build();//通過自定義擴(kuò)展方法 引用中間件app.UseSeason();//末端的中間件app.Run(async (context) =>{    await context.Response.WriteAsync("請(qǐng)求結(jié)束");});//運(yùn)行應(yīng)用app.Run();

    在對(duì)以上中間件應(yīng)用方面,我們能可以看出“基于約定的中間件”類型并沒有進(jìn)行服務(wù)注冊(cè),而“強(qiáng)類型中間件”類型卻進(jìn)行了服務(wù)注冊(cè),這是因?yàn)閮烧咴谔峁?shí)例的方式上有著本質(zhì)的區(qū)別。

    “基于約定的中間件”的實(shí)例是在應(yīng)用啟動(dòng)時(shí)便可提供的,并且只能指定的一個(gè)固定的生命周期模式“Singleton”,所以該類型中間件具有和應(yīng)用程序一樣的生存期,直到應(yīng)用程序關(guān)閉才會(huì)釋放。

    “強(qiáng)類型中間件”的實(shí)例并不是在應(yīng)用啟動(dòng)時(shí)提供的,它需要根據(jù)服務(wù)注冊(cè)時(shí)指定的生命周期,來決定創(chuàng)建提供的時(shí)機(jī)。例如“強(qiáng)類型中間件”注冊(cè)的生命周期為“Scoped”,那么依賴注入容器會(huì)根據(jù)客戶端的請(qǐng)求實(shí)時(shí)創(chuàng)建中間件的實(shí)例,請(qǐng)求處理完成后才會(huì)被釋放。

    總結(jié)

    中間件的使用地位在ASP.NET Core中絕對(duì)是毋庸置疑的,那么對(duì)于較為復(fù)雜的項(xiàng)目而言,自定義中間件的需求絕對(duì)是“繞不開的彎”,所以我們必須掌握自定義中間件的方式。

    本文介紹了3種可以實(shí)現(xiàn)自定義ASP.NET Core中間件的方式。其中第一種并不推崇作為實(shí)戰(zhàn)運(yùn)用的手段,其目的是為了讓我們明白:中間件最終的體現(xiàn)形式其實(shí)就是一個(gè)委托對(duì)象,該委托對(duì)象承載了請(qǐng)求上下信息,并具有傳遞性。在實(shí)際的使用中,我們可以在第二種和第三種中進(jìn)行選擇,也就是“強(qiáng)類型中間件”和“基于約定的中間件”,從兩者的特點(diǎn)上來看,“基于約定的中間件”在使用方面會(huì)更加的方便,但是其生命周期模式只能局限于Singleton。而“強(qiáng)類型中間件”可以通過服務(wù)注冊(cè)為中間件實(shí)例指定任意的生命周期模式,相比更加靈活。

    對(duì)于具體的選擇,我們想我們還是交給我們實(shí)際的運(yùn)用場(chǎng)景。

    如果想了解更多關(guān)于自定義 ASP.NET Core 中間件的方式,可以訪問如下的官方文檔:

    到此這篇關(guān)于ASP.NET Core自定義中間件的方式的文章就介紹到這了,更多相關(guān)ASP.NET Core自定義中間件內(nèi)容請(qǐng)搜索以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持!

    標(biāo)簽: ASP.NET
    日本不卡不码高清免费观看,久久国产精品久久w女人spa,黄色aa久久,三上悠亚国产精品一区二区三区
    免费在线亚洲欧美| 日韩三区免费| 99国产精品视频免费观看一公开| 国产精品99一区二区三| 久久久国产精品网站| 久久精品国产999大香线蕉| 日韩精品a在线观看91| 好吊一区二区三区| 亚洲一区黄色| 日韩激情网站| 日本视频一区二区| 美女视频网站久久| 日本欧美久久久久免费播放网| 日韩精品国产精品| 国产一区福利| 黄色在线观看www| 国产夫妻在线| 狠狠操综合网| 亚洲精选91| 手机在线电影一区| 黄色日韩精品| 欧美在线首页| 国产h片在线观看| 在线一区免费| 国产亚洲欧美日韩精品一区二区三区 | 婷婷精品在线观看| 久久99视频| 午夜欧美精品| 麻豆精品国产91久久久久久| 亚洲国产综合在线看不卡| 婷婷成人av| 国产aⅴ精品一区二区三区久久| 国产99久久| 国产精久久久| 日韩中文字幕麻豆| 国产欧美一区二区三区精品酒店| 亚洲免费成人| 美女福利一区二区三区| 中文字幕乱码亚洲无线精品一区| 久久中文字幕一区二区| 男人的天堂久久精品| 日韩精品永久网址| 国产精品一级| 亚洲一区导航| 欧美色图国产精品| 久久久久观看| 综合激情网站| 久久久久久久久久久9不雅视频| 欧美一区免费| 色8久久久久| 亚洲欧美成人综合| 1000部精品久久久久久久久| 国产一区二区三区久久| 91成人精品在线| 在线一区二区三区视频| 91成人网在线观看| 色天使综合视频| 久久99国产精品视频| 国产精品亚洲综合久久| 亚洲精品福利| 综合色一区二区| 国产精品嫩草99av在线| 久久九九精品| 91精品国产91久久久久久黑人| 日韩欧美视频专区| 精品三级在线| 国产一区国产二区国产三区| 精品亚洲二区| 国产精品久久久久av电视剧| 成人精品亚洲| 亚洲综合三区| 国产欧美自拍一区| 六月丁香综合在线视频| 麻豆国产精品视频| 999视频精品| 久久国产高清| 亚洲免费成人av在线| 欧美日韩亚洲一区二区三区在线| 欧美日本不卡| 特黄特色欧美大片| 亚洲视频二区| 亚洲激情社区| 国产精品欧美一区二区三区不卡| 国产精品伦理久久久久久| 激情自拍一区| 国产九九精品| 免费av一区二区三区四区| 色狠狠一区二区三区| 国产一区2区| 蜜桃视频第一区免费观看| 久久香蕉网站| 尤物在线精品| 久久99蜜桃| 男女性色大片免费观看一区二区| 国产精品22p| 在线看片一区| 蜜桃av.网站在线观看| 亚洲精品护士| 99久久亚洲精品蜜臀| 国产精品一二| 亚洲精品伊人| 欧美日韩精品免费观看视频完整| 久久精品一本| 国产九九精品| 97久久超碰| 久久福利毛片| 蜜桃tv一区二区三区| 欧美久久香蕉| 美女网站久久| 欧美日韩一区二区综合| 久久精品国产99国产| 日本精品在线播放| 亚洲日本免费电影| 亚洲一区区二区| 欧美日韩在线网站| 久久久久久美女精品| 成人欧美一区二区三区的电影| 国产乱码精品| 欧美日韩调教| 国产午夜精品一区在线观看| 综合亚洲视频| 日本一区中文字幕| 亚洲激情不卡| 视频在线观看国产精品| 国产精品毛片在线| 视频一区欧美日韩| 日精品一区二区三区| 日韩av在线免费观看不卡| 日韩视频1区| 国产精东传媒成人av电影| 欧美国产另类| 97se综合| 久久视频精品| 蜜臀久久99精品久久久画质超高清| 国产亚洲亚洲| 91p九色成人| 精品一区二区三区中文字幕视频| 欧美视频久久| 日韩电影二区| 黄色亚洲免费| 日韩不卡一区二区| 国产精品不卡| 好吊视频一区二区三区四区| 视频在线观看一区二区三区| 日韩三级久久| 综合日韩av| 伊人成人在线视频| 欧美一区久久| 久久婷婷久久| 日本午夜精品一区二区三区电影| 精品国产网站| 久久xxxx精品视频| 日韩久久一区| av亚洲一区二区三区| 日韩电影免费在线观看| 国产精品久久久久9999高清| 啪啪国产精品| 国产精品资源| 国产精品美女| 国产成人免费精品| 国产精品普通话对白| 久久精品国产精品亚洲毛片| 91久久黄色| 国产欧美日韩综合一区在线播放| 日韩和的一区二在线| 国产探花一区| 国产伦理一区| 蜜臀久久99精品久久一区二区| 日韩二区三区在线观看| 久久精品1区| 国产一区2区| 国产精品乱战久久久| 午夜精品一区二区三区国产| 久久精品九色| 国产欧美一区| 日韩 欧美一区二区三区| 亚洲成人精选| 久久久久久黄| 在线手机中文字幕| 欧美激情福利| 欧美在线精品一区| 亚洲免费毛片| 最新亚洲一区| 精品中文一区| 欧美精品一区二区久久| 中文字幕高清在线播放| 成人在线黄色| 国产一区二区精品久| 国产在线一区不卡| 黑人精品一区| 99久久久久国产精品| 久久人人精品| 国产精品试看| 亚洲天堂日韩在线| 亚洲精品一级二级三级| 亚洲视频二区| 国产精品nxnn| 精品三级av在线导航| 日韩不卡免费高清视频| 久久一级电影|