九色国产,午夜在线视频,新黄色网址,九九色综合,天天做夜夜做久久做狠狠,天天躁夜夜躁狠狠躁2021a,久久不卡一区二区三区

打開APP
userphoto
未登錄

開通VIP,暢享免費(fèi)電子書等14項(xiàng)超值服

開通VIP
ASP.NET Core 菜鳥之路:從Startup.cs說起
1.前言
本文主要是以Visual Studio 2017 默認(rèn)的 WebApi 模板作為基架,基于Asp .Net Core 1.0,本文面向的是初學(xué)者,如果你有 ASP.NET Core 相關(guān)實(shí)踐經(jīng)驗(yàn),歡迎在評(píng)論區(qū)補(bǔ)充。
與早期版本的 ASP.NET 對(duì)比,最顯著的變化之一就是配置應(yīng)用程序的方式, Global.asax、FilterConfig.cs 和 RouteConfig.cs 統(tǒng)統(tǒng)消失了,取而代之的是 Program.cs 和 Startup.cs。Program.cs 作為 Web 應(yīng)用程序的默認(rèn)入口,不做任何修改的情況下,會(huì)調(diào)用同目錄下 Startup.cs 中的 ConfigureServices 方法 和 Configure 方法。
應(yīng)用啟動(dòng)的流程
對(duì)于初學(xué)者來說,第一次面對(duì) Startup.cs 往往無(wú)從下手,本文將一步步介紹作者的經(jīng)驗(yàn),但是不會(huì)涉入到內(nèi)部的代碼實(shí)現(xiàn)以及相關(guān)的原理,那并不是本文想要討論的范疇。
默認(rèn)的Startup.cs
相信我,這將是你邁出構(gòu)建靈活而強(qiáng)大的ASP.NET Core 應(yīng)用程序的第一步。2.配置參數(shù)選項(xiàng)
在官方文檔中提供多種方式來配置參數(shù)選項(xiàng):
文件格式(INI,JSON和XML)
命令行參數(shù)
環(huán)境變量
內(nèi)存中的 .NET 對(duì)象
用戶機(jī)密存儲(chǔ)
Azure 鍵值
自定義提供程序
雖然提供了很多選擇,但是我們只選擇其中的JSON文件和環(huán)境變量來提供配置參數(shù)。
2.1 Json配置參數(shù)選項(xiàng)
參考官方文檔的示例,我們?cè)?appsettings.json 加入如下的參數(shù):
appsettings.json
與此同時(shí),我們還需要一個(gè)類來映射這些配置參數(shù):
MyOptions.cs
思考一下 subsection 應(yīng)該是字典還是一個(gè)對(duì)象?如果是字典,是否可以為<string,dynamic>或者<string,object>?
好了,現(xiàn)在就差怎么讓他們聯(lián)系起來,只需在 ConfigureServices 方法中將他們配對(duì):
services.Configure<MyOptions>(Configuration);
最后就是解決怎么使用這些配置參數(shù)的問題了,舉個(gè)最簡(jiǎn)單的例子,我們可以在某個(gè)控制器中把我們的所有參數(shù)打印出來:
MyOptionsController
返回結(jié)果
不知道你有沒有發(fā)現(xiàn) MyOptions 類中有些屬性首字母大寫,有些屬性沒有,并不是與json文件中完全一致,也就是說可以忽略大小寫的。
回到之前的匹配環(huán)節(jié),我們可以發(fā)現(xiàn) services.Configure 的方法中似乎還有更多選擇,比如我們把之前的那一行代碼替換為:
services.Configure<MyOptions>(Configuration.GetSection("wizards"));//選擇wizards節(jié)點(diǎn)
返回結(jié)果空了
我們可以發(fā)現(xiàn)返回的對(duì)象里面的屬性都為null,這是因?yàn)閖son中的 "wizards"的節(jié)點(diǎn)并不能與我們的類匹配。
那么問題來了,如果匹配的代碼如下,又會(huì)產(chǎn)生什么樣的結(jié)果呢?先別急著回答,我會(huì)在下一節(jié)中給出答案。
2.2環(huán)境變量
環(huán)境變量,或者說系統(tǒng)變量,在windows中我們可以在系統(tǒng)屬性中配置:
windows中的環(huán)境變量
在Linux環(huán)境中也有相應(yīng)的配置,但是在開發(fā)過程中,我們可以在 Visual Studio 中配置:
vs中配置環(huán)境變量
在這之前,我們的Json文件中已經(jīng)有 "option1" 和 "option2"的參數(shù)選項(xiàng),那么會(huì)產(chǎn)生什么樣的結(jié)果呢?
顯然我們可以看到環(huán)境變量的參數(shù)覆蓋了Json文件的參數(shù)。而引起這種變化的原因還是需要回到Startup的初始化:
public Startup(IHostingEnvironment env) { var builder = new ConfigurationBuilder() .SetBasePath(env.ContentRootPath) .AddJsonFile("appsettings.json", optional: false, reloadOnChange: true)//必須的json文件,并且自動(dòng)重載 .AddJsonFile($"appsettings.{env.EnvironmentName}.json", optional: true)//不必須的json文件 .AddEnvironmentVariables();//啟用環(huán)境變量 Configuration = builder.Build(); }
從中我們可以看出環(huán)境變量的配置在讀取 Json 文件參數(shù)之后,這樣就會(huì)覆蓋已經(jīng)存在的同名參數(shù),而已經(jīng)從 Json 文件被匹配的參數(shù)并不會(huì)被清空(同樣適用于前一節(jié)提出的問題)。從另一方面來說,如果你不需要環(huán)境變量,則需要去掉 "AddEnvironmentVariables() ",以免覆蓋預(yù)期參數(shù)。
回到本節(jié)的中心,我們?yōu)槭裁磿?huì)需要環(huán)境變量呢?我個(gè)人會(huì)在Dockerfile中配置一些環(huán)境變量,比如某種服務(wù)的訪問地址、某中功能的開關(guān)等等。下面舉例說說兩個(gè)常用的環(huán)境變量:
ASPNETCORE_URLS 如果你沒有指定對(duì)應(yīng)的 Url 監(jiān)聽地址,可以通過該參數(shù)修改,如設(shè)置為 "http://*:80"。
ASPNETCORE_ENVIRONMENT 開發(fā)環(huán)境(Development)、預(yù)演環(huán)境(Staging)、生產(chǎn)環(huán)境(Production),將在工作環(huán)境一節(jié)中做詳細(xì)介紹。不同的工作環(huán)境將使得整個(gè)軟件流程變得清晰。
2.3配置參數(shù)小貼士
參數(shù)有多種來源,如不需要勿增來源。
要注意"最近原則",避免參數(shù)同名引起沖突。
參數(shù)的key可以忽略大小寫,所以環(huán)境變量中的 "OPTION2" 可以引起覆蓋 Json文件中的 "option2" 的效果。
為復(fù)雜參數(shù)選擇合適的類型很重要,比如字典還是對(duì)象的取舍。
3.依賴注入
依賴注入在 ASP.NET Core 中無(wú)處不存在,在之前打印參數(shù)的例子中同樣用到。依賴注入好處都有啥?為什么我們需要依賴注入?在ASP .NET Core 中文文檔中依賴注入的章節(jié) 很好地解釋了:
你應(yīng)該設(shè)計(jì)你的依賴注入服務(wù)來獲取它們的合作者。這意味著在你的服務(wù)中避免使用有狀態(tài)的靜態(tài)方法調(diào)用(代碼被稱為static cling)和直接實(shí)例化依賴的類型。當(dāng)選擇實(shí)例化一個(gè)類型還是通過依賴注入請(qǐng)求它時(shí),它可以幫助記住這句話,New is Glue。通過遵循面向?qū)ο笤O(shè)計(jì)的 SOLID 原則,你的類將傾向于小、易于分解及易于測(cè)試。
3.1注冊(cè)服務(wù)以及簡(jiǎn)單使用
為了方便下一節(jié)測(cè)試,我準(zhǔn)備三個(gè)文件,簡(jiǎn)單的接口、該接口的實(shí)現(xiàn)類,擁有接口成員的類:
IRepository
MemoryRepository
ProductTotalizer
接下來,我們使用 ASP.NET Core 自帶的 DI 來注冊(cè)服務(wù):
注冊(cè)服務(wù)
可以看到,注冊(cè)對(duì)象有很多種方法,并且我們可以管理對(duì)象的生命周期。注冊(cè)完對(duì)象,我們就可以在我們需要的地方注入對(duì)應(yīng)的對(duì)象了,還是最簡(jiǎn)單的例子——在控制器中使用:
注入到控制器中
對(duì)于控制器,我們有三種方式注入對(duì)象:構(gòu)造函數(shù)、控制器動(dòng)作、屬性注入。然而,在一般的類中,使用自帶的 DI 只能是構(gòu)造函數(shù)注入。到底是哪種方式好,見仁見智。
3.2生命周期
ASP.NET Core 服務(wù)可以被配置為以下生命周期:
瞬時(shí)(Transient) 在它們每次請(qǐng)求時(shí)都會(huì)被創(chuàng)建。這一生命周期適合輕量級(jí)的,無(wú)狀態(tài)的服務(wù)。
作用域 (Scoped) 在每次請(qǐng)求中只創(chuàng)建一次。
單例(Singleton) 在它們第一次被請(qǐng)求時(shí)創(chuàng)建(或者如果你在 ConfigureServices運(yùn)行時(shí)指定一個(gè)實(shí)例)并且每個(gè)后續(xù)請(qǐng)求將使用相同的實(shí)例。
我們將通過逐步更改 IRepository 的生命周期來看看會(huì)發(fā)生什么事情。
首先是瞬時(shí):
瞬時(shí)
接著是作用域:
作用域
最后是單例:
單例
瞬時(shí)很好理解,類似每次都會(huì)new了一個(gè)對(duì)象。而對(duì)于作用域,如果一次請(qǐng)求中,有兩個(gè)甚至多個(gè)非單例對(duì)象引用到同一個(gè)作用域類型時(shí),他們將會(huì)收獲同一個(gè)實(shí)例。單例也很好理解,從頭到尾都是同一個(gè)實(shí)例。
控制單一變量,如果只是改變 ProductTotalizer 的生命周期而不是改變 IRepository 的生命周期的話,會(huì)發(fā)生什么情況呢?
3.3依賴注入小貼士
遵循 SOLID 原則,考慮一下哪些是需要依賴注入的,避免硬編碼。
合理考慮生命周期,假如某個(gè)類型在不同上下文中需要不同生命周期時(shí),是否需要顯式命名區(qū)分?還是考慮結(jié)構(gòu)是否合理?
避免靜態(tài)訪問服務(wù)。
避免靜態(tài)訪問 HttpContext 。
4.啟用擴(kuò)展
在項(xiàng)目中我們往往會(huì)添加許多擴(kuò)展,比如用于API文檔說明的Swagger、計(jì)劃任務(wù)的Hangfire、壓縮響應(yīng)的GZIP、跨域訪問、日志擴(kuò)展等等。他們的共同點(diǎn)就是需要先安裝相應(yīng)的nuget包,然后在 ConfigureServices() 方法中配置服務(wù),最后在 Configure() 方法中啟用。
我們以Swagger為例,首先是安裝對(duì)應(yīng)的 nuget 包—— Swashbuckle。
接著是配置擴(kuò)展:
配置Swagger
最后就是啟用 Swagger 了:
啟用 Swagger
最后我們?cè)L問 Swagger 的地址看看效果:
在線API文檔
5.中間件
中間件是用于組成應(yīng)用程序管道來處理請(qǐng)求和響應(yīng)的組件。管道內(nèi)的每一個(gè)組件都可以選擇是否將請(qǐng)求交給下一個(gè)組件、并在管道中調(diào)用下一個(gè)組件之前和之后執(zhí)行某些操作。請(qǐng)求委托被用來建立請(qǐng)求管道,請(qǐng)求委托處理每一個(gè) HTTP 請(qǐng)求。
中間件處理請(qǐng)求
舉一個(gè)簡(jiǎn)單的例子(更復(fù)雜的可以在中間件依賴注入對(duì)象),從 cookie 中獲取 token 并附加到請(qǐng)求頭中:
獲取 cookie 中的token
與啟用擴(kuò)展一樣,我們同樣是需要在 Configure()方法中啟用中間件:
app.UseMiddleware<JWTInHeaderMiddleware>();
如果我們有多個(gè)中間件呢,中間件的順序可能會(huì)影響到響應(yīng)結(jié)果,但并不是總是線性相關(guān)的。例如,我們新增一個(gè)對(duì)響應(yīng)狀態(tài)碼處理的中間件:
響應(yīng)狀態(tài)碼處理中間件
我們把它加到其他中間件的最前面:
app.UseMiddleware<StatusCodeMiddleware>();//....app.UseMiddleware<JWTInHeaderMiddleware>();
雖然對(duì)狀態(tài)碼處理的中間件是最前面,但可以在請(qǐng)求的最后關(guān)頭對(duì)請(qǐng)求結(jié)果進(jìn)行處理。當(dāng)然,如果中間有某個(gè)中間件短路了(沒有傳遞到下一個(gè)中間件),就會(huì)讓我們前功盡棄。
測(cè)試多個(gè)中間件處理請(qǐng)求
6.過濾器
與中間相似,過濾器同樣可以對(duì)請(qǐng)求的前后執(zhí)行特定代碼,但是過濾器可以配置為全局有效、僅對(duì)控制器有效或是僅對(duì) Action 有效,比中間件更具有靈活性。
過濾器處理請(qǐng)求
另外,過濾器從類型上還能分為:授權(quán)過濾器、資源過濾器、Action過濾器、結(jié)果過濾器。很容易實(shí)現(xiàn)面向切面編程,降低了耦合。
這里舉一個(gè)我最喜歡的過濾器——對(duì)請(qǐng)求的模型進(jìn)行驗(yàn)證:
請(qǐng)求模型過濾器
在控制器或 Action 使用,只需加上特性即可:
控制器中使用過濾器
當(dāng)然,模型驗(yàn)證的過濾器往往具有全局性,所以我一般是加在 services.AddMvc 中:
services.AddMvc(config=> { config.Filters.Add(new ValidateModel()); });
模型驗(yàn)證過濾器效果
7.工作環(huán)境
ASP.NET Core 提供了許多功能和約定來允許開發(fā)者更容易的控制在不同的環(huán)境中他們的應(yīng)用程序的行為。當(dāng)發(fā)布一個(gè)應(yīng)用程序從開發(fā)到預(yù)演再到生產(chǎn),為環(huán)境設(shè)置適當(dāng)?shù)沫h(huán)境變量允許對(duì)應(yīng)用程序的調(diào)試,測(cè)試或生產(chǎn)使用進(jìn)行適當(dāng)?shù)膬?yōu)化。
在軟件開發(fā)的生命周期中,在不同的工作環(huán)境中往往是不同的狀態(tài)。比如說,在測(cè)試或者預(yù)演環(huán)境中,啟用Swagger擴(kuò)展、控制臺(tái)打印日志、允許跨域,而在生產(chǎn)環(huán)境中,往往處于安全、性能或者其他考慮,這些功能是需要禁止的。對(duì)于 MVC 開發(fā)者來說,在開發(fā)過程中會(huì)使用本地的JS、Css、圖片等文件,而在生產(chǎn)環(huán)境中這些文件往往是從CDN中獲取。
配置工作環(huán)境
8.結(jié)語(yǔ)
ASP.NET Core 提供了強(qiáng)大而靈活的配置機(jī)制,每個(gè)點(diǎn)展開都像是一片新的天地。即使是經(jīng)驗(yàn)豐富的開發(fā)者,也不能自稱完全掌握全部機(jī)制。隨著 .NET Core 的完善和發(fā)展,Startup.cs 也將越來越復(fù)雜。越是復(fù)雜,就越是要小心,如無(wú)需要,勿增實(shí)體!
9.相關(guān)引用
Configuration in ASP.NET Core
ASP.NET Core 中文文檔
本文采用知識(shí)共享署名-非商業(yè)性使用-相同方式共享 3.0 中國(guó)大陸許可協(xié)議
轉(zhuǎn)載請(qǐng)注明:作者張蘅水
打賞作者
本站僅提供存儲(chǔ)服務(wù),所有內(nèi)容均由用戶發(fā)布,如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請(qǐng)點(diǎn)擊舉報(bào)。
打開APP,閱讀全文并永久保存 查看更多類似文章
猜你喜歡
類似文章
Nunjucks
Jinja2 中文文檔
JS高級(jí)
httprunner學(xué)習(xí)9-完整的用例結(jié)構(gòu)(yaml&json)
深入理解javascript原型和閉包(15)
R語(yǔ)言筆記6:在R中寫一些簡(jiǎn)單的函數(shù)、functions基礎(chǔ)和作用域
更多類似文章 >>
生活服務(wù)
熱點(diǎn)新聞
分享 收藏 導(dǎo)長(zhǎng)圖 關(guān)注 下載文章
綁定賬號(hào)成功
后續(xù)可登錄賬號(hào)暢享VIP特權(quán)!
如果VIP功能使用有故障,
可點(diǎn)擊這里聯(lián)系客服!

聯(lián)系客服