日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程语言 > asp.net >内容正文

asp.net

这批.Net程序员水平不行啊!居然ASP.NET Core Middleware都不会用

發布時間:2023/12/4 asp.net 28 豆豆
生活随笔 收集整理的這篇文章主要介紹了 这批.Net程序员水平不行啊!居然ASP.NET Core Middleware都不会用 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

最近問了幾個面試同一個問題:如果有多個自定義Middleware,如何控制它們的執行順序(比如先判斷用戶合法再寫訪問日志)。居然大部分人答不上來?!?

對此,你有什么看法?

ASP.NET Core Middleware的調用順序

這里我直接貼上官方文檔[1]中的圖片:?

ASP.NET Core 請求管道包含一系列請求委托,依次調用。而調用順序實際上就是我們在Startup.cs中注冊(使用UseMiddlewareExtensions.UseMiddleware方法)它們的順序。

示例代碼如下:

public?void?ConfigureServices(IServiceCollection?services) {//注冊生命周期services.AddTransient<TransientMiddleware>();services.AddScoped<ScopedMiddleware>(); }public?void?Configure(IApplicationBuilder?app,?IWebHostEnvironment?env) {//注冊調用順序app.UseMiddleware<TransientMiddleware>();app.UseMiddleware<ScopedMiddleware>(); }

但這種方式,對于調整自定義Middleware的需求,需要經常修改Startup.cs,而且會使代碼比較凌亂,可讀性較差。

可以使用下面的方式,簡化注冊代碼:

public?void?ConfigureServices(IServiceCollection?services) {services.AddMiddlewares(); } public?void?Configure(IApplicationBuilder?app,?IWebHostEnvironment?env) {app.UseMiddlewares(); }

實現方式

1.定義Attribute

MiddlewareRegisterAttribute將放在每個Middleware實現類上,表明它是需要被注冊的Middleware。

[AttributeUsage(AttributeTargets.Class)] public?class?MiddlewareRegisterAttribute?:?Attribute {//注冊順序public?int?Sort?{?get;?set;?}?=?int.MaxValue;//生命周期public?ServiceLifetime?Lifetime?{?get;?set;?}?=?ServiceLifetime.Scoped; }

2.定義注冊信息類

MiddlewareRegisterInfo用于存放Middleware的注冊信息,供注冊方法調用。

public?class?MiddlewareRegisterInfo {public?MiddlewareRegisterInfo(Type?type,MiddlewareRegisterAttribute?attribute){Type?=?type;Sort?=?attribute.Sort;Lifetime?=?attribute.Lifetime;}public?Type?Type?{?get;?private?set;?}public?int?Sort?{?get;?private?set;?}public?ServiceLifetime?Lifetime?{?get;?private?set;?} }

2.實現注冊擴展方法

讀取Assembly中的Type, 如果存在MiddlewareRegisterAttribute就把它放入List<MiddlewareRegisterInfo>列表中,最后根據Sort屬性順序依次注冊,代碼如下:

public?static?class?MiddlewareRegisterExtensions {private?static?readonly?IEnumerable<MiddlewareRegisterInfo>?_middlewareRegisterInfos?=?GetMiddlewareRegisterInfos();public?static?IServiceCollection?AddMiddlewares(this?IServiceCollection?services){foreach?(var?middlewareRegisterInfo?in?_middlewareRegisterInfos){switch?(middlewareRegisterInfo.Lifetime){case?ServiceLifetime.Singleton:services.AddSingleton(middlewareRegisterInfo.Type);break;case?ServiceLifetime.Transient:services.AddTransient(middlewareRegisterInfo.Type);break;default:services.AddScoped(middlewareRegisterInfo.Type);break;}}return?services;}public?static?IApplicationBuilder?UseMiddlewares(this?IApplicationBuilder?applicationBuilder){foreach?(var?middlewareRegisterInfo?in?_middlewareRegisterInfos){applicationBuilder.UseMiddleware(middlewareRegisterInfo.Type);}return?applicationBuilder;}private?static?List<MiddlewareRegisterInfo>?GetMiddlewareRegisterInfos(){var?middlewareRegisterInfos?=?new?List<MiddlewareRegisterInfo>();//所有包含Middleware的Assemblyvar?assemblies?=?new?Assembly[]?{?typeof(Startup).Assembly?};foreach?(var?assembly?in?assemblies){foreach?(var?type?in?assembly.GetTypes().Where(x?=>?!x.IsAbstract)){var?attribute?=?type.GetCustomAttribute<MiddlewareRegisterAttribute>();if?(attribute?!=?null){middlewareRegisterInfos.Add(new?MiddlewareRegisterInfo(type,?attribute));}}}return?middlewareRegisterInfos.OrderBy(p=>p.Sort).ToList();} }

測試一下

創建3個Middleware,功能僅僅是輸出日志:

[MiddlewareRegister(Sort?=?100)] public?class?OneMiddleware?:?IMiddleware {private?readonly?ILogger<OneMiddleware>?logger;public?OneMiddleware(ILogger<OneMiddleware>?logger){this.logger?=?logger;}public?async?Task?InvokeAsync(HttpContext?context,?RequestDelegate?next){logger.LogInformation("One");await?next(context);} }

Sort用100、200、300,方便后面修改排序。

運行效果如下圖:

現在,將ThreeMiddleware的Sort改為150,調整注冊順序,再次運行,效果如下圖:?

結論

當然,這個解決方案也存在一些缺點,比如修改排序的位置移到每個Middleware,比較分散。但整體來說,代碼更易讀

如果你有其他實現方式,歡迎到公眾號后臺留言指教。

如果你覺得這篇文章對你有所啟發,請關注我的個人公眾號”My IO“,記住我!

參考資料

[1]

官方文檔: https://docs.microsoft.com/zh-cn/aspnet/core/fundamentals/middleware

總結

以上是生活随笔為你收集整理的这批.Net程序员水平不行啊!居然ASP.NET Core Middleware都不会用的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。