ASP.NET Core 運(yùn)行原理分析

SP.NET Core 運(yùn)行原理剖析

1. ASP.NET Core 運(yùn)行原理剖析

1.1. 概述

1.2. 文件配置

1.2.1. Starup文件配置

Configure

ConfigureServices

1.2.2. appsetting.json配置

1.3. 處理管道(中間件)

1.4 總結(jié)

1.1. 概述

在ASP.NET Core之前绳姨,ASP.NET Framework應(yīng)用程序由IIS加載蜜猾。Web應(yīng)用程序的入口點(diǎn)由InetMgr.exe創(chuàng)建并調(diào)用托管筹吐。以初始化過程中觸發(fā)HttpApplication.Application_Start()事件。開發(fā)人員第一次執(zhí)行代碼的機(jī)會(huì)是處理Application_StartGlobal.asax中的事件备韧。在ASP.NET Core中摊灭,Global.asax文件不再可用被济,已被新的初始化過程替代拍冠。

ASP.NET Core 應(yīng)用程序是在.NET Core 控制臺(tái)程序下調(diào)用特定的庫(kù),這是ASP.NET Core應(yīng)用程序開發(fā)的根本變化缴阎。所有的ASP.NET托管庫(kù)都是從Program開始執(zhí)行缠黍,而不是由IIS托管。也就是說.NET工具鏈可以同時(shí)用于.NET Core控制臺(tái)應(yīng)用程序和ASP.NET Core應(yīng)用程序药蜻。

usingSystem;usingMicrosoft.AspNetCore.Hosting;namespaceaspnetcoreapp{publicclassProgram{publicstaticvoidMain(string[] args){varhost =newWebHostBuilder()? ? ? ? ? ? ? ? .UseKestrel()//指定宿主程序?yàn)镵estrel.UseStartup()// 調(diào)用Startup.cs類下的Configure 和 ConfigureServices.Build();? ? ? ? ? ? host.Run();? ? ? ? }? ? }}

以上是Program類中Main方法的示例代碼瓷式,Main方法負(fù)責(zé)初始化Web主機(jī),調(diào)用Startup和執(zhí)行應(yīng)用程序语泽。主機(jī)將調(diào)用Startup類下面的Configure和ConfigureServices方法贸典。

1.2. 文件配置

1.2.1. Starup文件配置

對(duì)于一個(gè)ASP.NET Core 程序而言,Startup?類是必須的踱卵。ASP.NET Core在程序啟動(dòng)時(shí)會(huì)從Program類中開始執(zhí)行廊驼,然后再找到UseStartup<Startup>中找到配置的Startup的類据过,如果不指定Startup類會(huì)導(dǎo)致啟動(dòng)失敗。

在Startup中必須定義Configure方法妒挎,而ConfigureServices方法則是可選的绳锅,方法會(huì)在程序第一次啟動(dòng)時(shí)被調(diào)用,類似傳統(tǒng)的ASP.NET MVC的路由和應(yīng)用程序狀態(tài)均可在Startup中配置酝掩,也可以在此初始化所需中間件鳞芙。

Configure

在ASP.NET Core 應(yīng)用程序中Configure方法用于指定中間件以什么樣的形式響應(yīng)HTTP請(qǐng)求。

usingSystem;usingMicrosoft.AspNetCore.Builder;usingMicrosoft.AspNetCore.Hosting;usingMicrosoft.AspNetCore.Http;namespaceaspnetcoreapp{publicclassStartup{publicStartup(IConfiguration configuration){? ? ? ? ? ? Configuration = configuration;? ? ? ? }publicIConfiguration Configuration {get; }publicvoidConfigure(IApplicationBuilder app, IHostingEnvironment env){if(env.IsDevelopment())? ? ? ? ? ? {? ? ? ? ? ? ? ? app.UseDeveloperExceptionPage();? ? ? ? ? ? ? ? app.UseBrowserLink();? ? ? ? ? ? }else{? ? ? ? ? ? ? ? app.UseExceptionHandler("/Home/Error");? ? ? ? ? ? }? ? ? ? ? ? ? ? ? ? ? ? app.UseStaticFiles();? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? app.UseMvc(routes =>? ? ? ? ? ? {? ? ? ? ? ? ? ? routes.MapRoute(? ? ? ? ? ? ? ? ? ? name:"default",? ? ? ? ? ? ? ? ? ? template:"{controller=Home}/{action=Index}/{id?}");? ? ? ? ? ? });? ? ? ? }? ? }}

ASP.NET Core是通過對(duì)IApplicationBuilder進(jìn)行擴(kuò)展來構(gòu)建中間件的期虾, 上面代碼中每個(gè)use擴(kuò)展方法都是將中間件添加到請(qǐng)求管道原朝。也可以給Configure方法附加服務(wù)(如:IHostingEnvironment)這些服務(wù)在ConfigureServices方法中被初始化。

用ASP.NET Core項(xiàng)目模板添加的應(yīng)用程序镶苞,默認(rèn)添加的幾個(gè)中間件:

UseStaticFiles 允許應(yīng)用程序提供靜態(tài)資源喳坠。

UseMvc 將MVC添加到管道并允許配置路由。

ConfigureServices

ConfigureServices方法是應(yīng)用程序運(yùn)行時(shí)將服務(wù)添加到容器中茂蚓,用ASP.NET Core項(xiàng)目模板的時(shí)候默認(rèn)會(huì)將MVC的服務(wù)添加到容器中:

publicvoidConfigureServices(IServiceCollection services){? ? services.AddMvc();}

接下來舉一個(gè)例子壕鹉,在實(shí)際應(yīng)用中ConfigureServices方法和Configure方法配合使用,在ASP.NET Core中有一個(gè)UI開發(fā)框架Telerik UI for ASP.NET Core聋涨,它有60多個(gè)UI組件晾浴,不僅支持ASP.NET Core的跨平臺(tái)布署模式,而且還支持前端自適應(yīng)渲染牛郑。

當(dāng)在項(xiàng)目中應(yīng)用Telerik UI的時(shí)候怠肋,首先在項(xiàng)目中引用相關(guān)的包敬鬓,然后再在ConfigureServices方法中將Kendo UI服務(wù)添加到容器中:

publicvoidConfigureServices(IServiceCollection services){? ? services.AddKendo();}

接下來淹朋,在Configure中設(shè)置Kendo UI

publicvoidConfigure(IApplicationBuilder app, IHostingEnvironment env){//...app.UseKendo(env);}

1.2.2. appsetting.json配置

Configuration API 提供了一個(gè)基于鍵-值對(duì)來配置應(yīng)用程序的方法,在運(yùn)行時(shí)可以從多個(gè)來源來讀取配置钉答。鍵-值對(duì)可以分組形成多層結(jié)構(gòu)础芍。鍵-值對(duì)可以配置在不同的地方,如:文件数尿、內(nèi)存等仑性,其中放在內(nèi)存中不能持久化,這里筆者選擇將其配置在appsetting.json文件里面右蹦。

配置appsetting文件

{"key1":"字符串","key2":2,"key3":true,"parentObj": {"key1":"sub-key1"},"members": [? ? {"name":"Lily","age":"18"},? ? {"name":"Lucy","age":"17"}? ]}

一個(gè)分層結(jié)構(gòu)的JSON文件诊杆,鍵(如:key1)作為索引器,值作為參數(shù)何陆,類型可以為:字符串晨汹、數(shù)字、布爾贷盲、對(duì)象淘这、數(shù)組。下面具體來看下在應(yīng)用中怎樣使用。

在應(yīng)用程序加加載和應(yīng)用配置文件

publicstaticIConfigurationRoot Configuration {get;set; }publicstaticvoidMain(string[] args =null){varbuilder =newConfigurationBuilder()? ? ? ? .SetBasePath(Directory.GetCurrentDirectory())? ? ? ? .AddJsonFile("appsettings.json");? ? Configuration = builder.Build();? ? Console.WriteLine($"key1 ={Configuration["key1"]}");? ? Console.WriteLine($"key2 ={Configuration["key2"]}");? ? Console.WriteLine($"subkey1 ={Configuration["parentObj:key1"]}");? ? Console.WriteLine();? ? Console.WriteLine("members:");? ? Console.Write($"{Configuration["members:0:name"]}, ");? ? Console.WriteLine($"age{Configuration["members:0:age"]}");? ? Console.Write($"{Configuration["members:1:name"]}, ");? ? Console.WriteLine($"age{Configuration["members:1:age"]}");? ? Console.WriteLine();? ? Console.WriteLine("Press a key...");? ? Console.ReadKey();}

由于加載的是一個(gè)JSON文件,所以文件加載進(jìn)來以后程序可以直接將它當(dāng)作一個(gè)JSON對(duì)象來使用铝穷。如果有過動(dòng)態(tài)語(yǔ)言使用經(jīng)驗(yàn)的同學(xué)來說這種方式就比較熟悉了钠怯。只在這里訪問屬性的時(shí)候?qū)⑵綍r(shí)常見的.變成了:,這和寫的JSON對(duì)象更接近曙聂。

1.3. 處理管道(中間件)

在ASP.NET Core應(yīng)用程序中使用中間件晦炊,應(yīng)用程序所做的任何事情(包括服務(wù)器中的靜態(tài)文件)都是由中間件來完成的。沒有任何中間件的應(yīng)用程序在請(qǐng)求的出錯(cuò)時(shí)候簡(jiǎn)單返回404 Not Found筹陵。中間件可以讓您完全控制請(qǐng)求的處理方式刽锤,并且讓您的應(yīng)用程序更加精簡(jiǎn)。

當(dāng)接收到一個(gè)請(qǐng)求時(shí)朦佩,請(qǐng)求會(huì)交給中間件構(gòu)成的中間件管道進(jìn)行處理并思,管道就是多個(gè)中間件構(gòu)成,請(qǐng)求從一個(gè)中間件的一端進(jìn)入语稠,從中間件的另一端出來宋彼,每個(gè)中間件都可以對(duì)HttpContext請(qǐng)求開始和結(jié)束進(jìn)行處理:

在ASP.NET Core中可以用Run、Map和Use三種方式來配置HTTP管道仙畦。Run 方法稱為短路管道(因?yàn)樗粫?huì)調(diào)用 next 請(qǐng)求委托)输涕。因此,Run方法一般在管道尾部被調(diào)用慨畸。Run 是一種慣例莱坎,有些中間件組件可能會(huì)暴露他們自己的 Run方法,而這些方法只能在管道末尾處運(yùn)行寸士。下面兩段代碼是等效的檐什,因?yàn)閁se沒有調(diào)用next方法

Run方法示例代碼

publicvoidConfigure(IApplicationBuilder app, IHostingEnvironment env){? ? app.Run(asynccontext =>? ? ? ? {awaitcontext.Response.WriteAsync("environment "+ env);? ? ? ? });}

Use方法不執(zhí)行next時(shí)示例代碼

publicvoidConfigure(IApplicationBuilder app, IHostingEnvironment env){? ? app.Use(async(context, next) =>? ? ? ? {awaitcontext.Response.WriteAsync("environment "+ env);? ? ? ? });}

在.NET Core 中約定了Map*擴(kuò)展被用于分支管道,當(dāng)前的實(shí)現(xiàn)已支持基于請(qǐng)求路徑或使用謂詞來進(jìn)入分支弱卡。Map擴(kuò)展方法用于匹配基于請(qǐng)求路徑的請(qǐng)求委托乃正。Map只接受路徑,并配置單獨(dú)的中間件管道的功能婶博。

privatestaticvoidHandleMapUrl(IApplicationBuilder app){? ? app.Run(asynccontext =>? ? {awaitcontext.Response.WriteAsync("Map Url Test Successful");? ? });}publicvoidConfigureMapping(IApplicationBuilder app, IHostingEnvironment env){? ? app.Map("/mapurl", HandleMapUrl);}

上例中是一個(gè)用Map方法來接受路徑進(jìn)入分支管道瓮具,也就是說所有基于/mapurl路徑請(qǐng)求都會(huì)被管道中的HandleMapUrl方法所處理;如果想用謂詞來進(jìn)入中間件分支凡人,則要使用MapThen方法名党。MapThen方法允許以一種非常靈活的方式構(gòu)建中間管道。比如可以檢測(cè)查詢字符串是否具有'branch'來進(jìn)入分支:

privatestaticvoidHandleBranch(IApplicationBuilder app){? ? app.Run(asynccontext =>? ? {awaitcontext.Response.WriteAsync("Branch used.");? ? });}publicvoidConfigure(IApplicationBuilder app){? ? app.MapWhen(context => {returncontext.Request.Query.ContainsKey("branch");? ? }, HandleBranch);}

1.4 總結(jié)

這節(jié)講解了ASP.NET Core在運(yùn)行時(shí)首先加載Program類下面的Main方法挠轴,在Main方法中指定托管服務(wù)器传睹,并調(diào)用Startup類中的Configure和ConfigureServices方法等完成初始化;

在ASP.NET Core中 HTTP請(qǐng)求是以中間件管道的形式進(jìn)行處理忠荞,每個(gè)中間件都可以在HTTP請(qǐng)求開始和結(jié)束處理對(duì)它進(jìn)行處理蒋歌;

ASP.NET Core可以構(gòu)建跨平臺(tái)應(yīng)用帅掘,服務(wù)運(yùn)行在Http.Sys(僅適用于Windows平臺(tái))和Kestrel上,不需要用IIS進(jìn)行托管堂油,所以相比傳統(tǒng)ASP.NET來說性能更高效也更加靈活修档。

轉(zhuǎn)載注明出處http://www.cnblogs.com/vipyoumay/p/7567573.html

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市府框,隨后出現(xiàn)的幾起案子吱窝,更是在濱河造成了極大的恐慌,老刑警劉巖迫靖,帶你破解...
    沈念sama閱讀 219,427評(píng)論 6 508
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件院峡,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡系宜,警方通過查閱死者的電腦和手機(jī)照激,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,551評(píng)論 3 395
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來盹牧,“玉大人俩垃,你說我怎么就攤上這事√ⅲ” “怎么了口柳?”我有些...
    開封第一講書人閱讀 165,747評(píng)論 0 356
  • 文/不壞的土叔 我叫張陵,是天一觀的道長(zhǎng)有滑。 經(jīng)常有香客問我跃闹,道長(zhǎng),這世上最難降的妖魔是什么毛好? 我笑而不...
    開封第一講書人閱讀 58,939評(píng)論 1 295
  • 正文 為了忘掉前任望艺,我火速辦了婚禮,結(jié)果婚禮上睛榄,老公的妹妹穿的比我還像新娘荣茫。我一直安慰自己想帅,他們只是感情好场靴,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,955評(píng)論 6 392
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著港准,像睡著了一般旨剥。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上浅缸,一...
    開封第一講書人閱讀 51,737評(píng)論 1 305
  • 那天轨帜,我揣著相機(jī)與錄音,去河邊找鬼衩椒。 笑死蚌父,一個(gè)胖子當(dāng)著我的面吹牛哮兰,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播苟弛,決...
    沈念sama閱讀 40,448評(píng)論 3 420
  • 文/蒼蘭香墨 我猛地睜開眼喝滞,長(zhǎng)吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來了膏秫?” 一聲冷哼從身側(cè)響起右遭,我...
    開封第一講書人閱讀 39,352評(píng)論 0 276
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎缤削,沒想到半個(gè)月后窘哈,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,834評(píng)論 1 317
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡亭敢,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,992評(píng)論 3 338
  • 正文 我和宋清朗相戀三年滚婉,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片帅刀。...
    茶點(diǎn)故事閱讀 40,133評(píng)論 1 351
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡满哪,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出劝篷,到底是詐尸還是另有隱情哨鸭,我是刑警寧澤,帶...
    沈念sama閱讀 35,815評(píng)論 5 346
  • 正文 年R本政府宣布娇妓,位于F島的核電站像鸡,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏哈恰。R本人自食惡果不足惜只估,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,477評(píng)論 3 331
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望着绷。 院中可真熱鬧蛔钙,春花似錦、人聲如沸荠医。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,022評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)彬向。三九已至兼贡,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間娃胆,已是汗流浹背遍希。 一陣腳步聲響...
    開封第一講書人閱讀 33,147評(píng)論 1 272
  • 我被黑心中介騙來泰國(guó)打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留里烦,地道東北人凿蒜。 一個(gè)月前我還...
    沈念sama閱讀 48,398評(píng)論 3 373
  • 正文 我出身青樓禁谦,卻偏偏與公主長(zhǎng)得像,于是被迫代替她去往敵國(guó)和親废封。 傳聞我的和親對(duì)象是個(gè)殘疾皇子枷畏,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,077評(píng)論 2 355

推薦閱讀更多精彩內(nèi)容