解讀ASP.NET 5 & MVC6系列教程(4):核心技術(shù)與環(huán)境配置
asp.net 5是下一代的asp.net,該版本進行了全部重寫以適用于跨平臺,新新版本中,微軟引入了如下工具與命令:DNVM、DNX、DNU。
DNVM(.NET Version Manager):由于要實現(xiàn)跨平臺的目錄,微軟提供了DNVM功能,DNVM是ASP.NET最底層的內(nèi)容,他是一組Powershell腳本,用于啟動指定版本的ASP.NET運行環(huán)境,并且可以在同一臺機器的同一時間點上通過使用Nuget工具來管理各種版本的ASP.NET運行環(huán)境(DNX),以及進行相應(yīng)的升級操作。
DNX(.NET Execution Environment):DNX是ASP.NET程序的運行環(huán)境,用于啟動并運行ASP.NET程序。該運行環(huán)境包括了編譯系統(tǒng)、SDK工具集、Native CLR宿主環(huán)境??梢允褂肈NVM管理各種版本的DNX,如dnvm list
命令可以列出所有可用的DNX環(huán)境,而dnvm install 0.1-alpha-build-0446
則可以將指定版本的DNX安裝到.dnx文件夾,你可以在%USERPROFILE%\.dnx\runtimes
目錄下找到已安裝所有版本的DNX。不同的操作系統(tǒng)有不同的DNX版本。
dnx.exe:dnx.exe是用于啟動自宿主環(huán)境(Self-Hosting)的命令行工具,在使用命令行代碼進行自宿主環(huán)境啟動程序時,dnx負責(zé)查找并調(diào)用CLR Native Host,dnx命令是整個運行環(huán)境的入口點,你可以使用dnx run
來啟動程序。
dnu(DNX Utility):是一個命令行的包管理器,包含在DNX內(nèi),所以只要安裝了DNX,就可以使用dnu命令, 其可以用于恢復(fù)程序包、安裝程序包、部署程序包等等,比如把project.json里自定義的程序集自動下載下來進行使用。
DNX架構(gòu)及運行原理
DNX是ASP.NET程序運行的核心,其遵循如下兩個準(zhǔn)則:
DNX應(yīng)該是自包含的,DNX在解析完應(yīng)用程序依賴樹以后才能知道要使用哪個Core CLR包,所以在得到解析樹之前,DNX是無法加載任何CLR的,但Roslyn編譯器除外。依賴注入(Dependency Injection,簡稱DI)貫穿著整個系統(tǒng)棧,DI是DNX的一個核心部分,所有DNX上的類庫都構(gòu)建在DI之上。
DNX執(zhí)行環(huán)境的分層架構(gòu)如下:
Layer 0:Native Process
該層的功能非常簡單,主要就是用于查找并調(diào)用Layer 1
里的CLR Native Host
,并將系統(tǒng)相關(guān)的參數(shù)傳遞給native host
,以便后續(xù)使用。目前Windows下使用DNX.exe
來處理這個事情,而IIS也提供了一個中介(網(wǎng)站bin目錄下提供一個AspNet.Loader.dll
)可以將請求轉(zhuǎn)發(fā)給Native Host
;而Linux和Mac則通過其相應(yīng)版本的dnx來支持這項功能。
DNX用法:
dnx.exe --lib {paths} --appbase {path} [ProgramName]
--lib {paths}:程序集dll的保存地址(一般是引用的第三方程序集和項目預(yù)編譯程序集),該地址是Layer 2層的托管代碼入口點可以加載程序集的地方。
--appbase {path}:程序保存的目錄,默認為%CD%。
[ProgramName]:程序名稱,該程序所在的程序集(或者是含有Programe::Main
的dll)保存在--lib
路徑下,默認值是appbase\project.json
里的name。大多數(shù)情況下,該名稱都是包含著加載鏈的程序宿主(Microsoft.Net.ApplicationHost
)。但是,如果你的程序包含了入口點(Main方法),并被編譯到--lib
目錄下的話,你就可以使用該程序集的名稱作為[ProgramName]
,這種方式將完全忽略加載鏈并直接啟動你的程序。
Layer 1 : CLR Native Host
這一層的內(nèi)容依賴于你所選擇呢CLR版本,該層有如下兩個職責(zé):
啟動CLR,啟動哪個CLR取決于你選擇的CLR版本。如果是Core CLR
,該層會加載coreclr.dll
,配置并啟動運行環(huán)境,然后創(chuàng)建應(yīng)用程序域(AppDomain
),以便運行所有的托管代碼。調(diào)用托管代碼的入口點(Layer 2
),一旦Native Host
的入口點返回了該線程,就會把CLR的線程清理干凈并關(guān)閉,比如,卸載應(yīng)用程序域(AppDomain
)并停止運行環(huán)境。
Layer 2:Managed Entry Point
Layer 2層(托管代碼入口)是編寫托管代碼的第一層,其職責(zé)如下:
創(chuàng)建LoaderContainer
(其包含需要的ILoaders
),ILoader
負責(zé)根據(jù)程序集的名稱來加載程序集。CLR需要一個程序集的話,LoaderContainer
就會使用其ILoader
來解析所需要的程序集。從--lib
的路徑目錄下,用根ILoader
來加載程序集,并解析其依賴。調(diào)用程序的主入口點。
Layer 3:Application host/Application
如果開發(fā)人員將整個程序編譯成程序集放在libpath
目錄下,那該層就是你的應(yīng)用程序了。使用的時候,將含有程序入口點的程序集名稱作為[ProgramName]
的參數(shù)傳入即可,Layer 2
層會直接調(diào)用該程序集。
不過,一般其它情況下,都會使用一個應(yīng)用程序宿主(Application host
)來解析程序的依賴內(nèi)容并啟動運行程序。Microsoft.Net.ApplicationHost
是運行環(huán)境提供的應(yīng)用程序宿主,并擁有如下職責(zé):
解析project.json
里定義的各種依賴程序集。將一個ILoader
添加到LoaderContainer
,以便從各種地方(如源代碼、NuGet、Roslyn等)加載相應(yīng)的程序集。調(diào)用程序集的入口點,將其作為下一個參數(shù),傳遞給DNX.exe。
Layer 4:Application
這一層,就是開發(fā)人員開發(fā)的程序,其運行在應(yīng)用程序宿主之上。
環(huán)境配置:
要對ASP.NET 5程序的運行環(huán)境DNX進行配置,首先需要安裝并配置DNVM,不同的操作系統(tǒng)安裝DNVM的時候不太一樣,我們在這里大概講解一下。
Windows安裝命令:
//需要安裝powershell 3.0 @powershell -NoProfile -ExecutionPolicy unrestricted -Command "iex ((new-object net.webclient).DownloadString('https://raw.githubusercontent.com/aspnet/Home/master/dnvminstall.ps1'))"
Linux:
curl -sSL https://raw.githubusercontent.com/aspnet/Home/master/dnvminstall.sh | sh && source ~/.dnx/dnvm/dnvm.sh
Mac OS X:
在Mac上,首先要安裝Mac系統(tǒng)本身的包管理器Homebrew(http://brew.sh
),并使用brew tap aspnet/k
命令將指定到ASP.NET5相關(guān)的git存儲庫,比如執(zhí)行如下命令:
brew install dnvm
該命令將會自動從ttps://www.nuget.org/api/v2
上下載最新的DNX,下載以后,如果你的系統(tǒng)不識別dnvm的話,你還需要再執(zhí)行一下如下語句:
source dnvm.sh
上述DNVM安裝以后,系統(tǒng)會將dnvm文件復(fù)制到C:\Program Files\Microsoft DNX\Dnvm
目錄,并將C:\Program Files\Microsoft DNX\Dnvm
目錄添加到環(huán)境變量中,以便全局都可以使用。注意:這里只是安裝了DNVM,并沒有安裝任何版本的DNX,要安裝DNX的話,可以通過運行dnvm或dnvm help來查找相關(guān)的命令,具體命令如下:
dnvm upgrade [-x86][-x64] [-svr50][-svrc50] [-g|-global] [-proxy <ADDRESS>]
1.從feed源安裝最新版的DNX
2.為已安裝的DNX設(shè)置一個默認(default)別名
3.將DNX bin添加的用戶PATH環(huán)境變量中
4.-g|-global 在全局內(nèi)進行安裝(其它用戶也可以使用)
5.-f|-force 強制更新成最新版(即便最新版已經(jīng)安裝過了)
6.-proxy 訪問遠程服務(wù)器的時候使用特定的地址作為代理
dnvm install <semver>|<alias>|<nupkg>|latest [-x86][-x64] [-svr50][-svrc50] [-a|-alias <alias>] [-g|-global] [-f|-force]
1.| 從feed源安裝指定的DNX
2.從本地文件系統(tǒng)安裝指定的DNX
3.latest 從feed源安裝最新版的DNX
4.將DNX bin添加到當(dāng)前命令行的path環(huán)境變量中
5.-p|-persistent 將DNX bin添加到系統(tǒng)PATH環(huán)境變量中
6.-a|-alias 對指定安裝的DNX設(shè)置別名
7.-g|-global 在全局內(nèi)進行安裝
8.-f|-force 強制安裝指定的DNX(即便該版本已經(jīng)安裝過了)
dnvm use <semver>|<alias>|none [-x86][-x64] [-svr50][-svrc50] [-p|-persistent] [-g|-global]
1.| 將DNX bin添加到當(dāng)前命令行的path環(huán)境變量中
2.none 將DNX bin從當(dāng)前命令行的path環(huán)境變量中刪除
3.-p|-persistent 將DNX bin添加到系統(tǒng)PATH環(huán)境變量中
4.-g|-global 組合使用-p將用戶PATH修改成系統(tǒng)PATH
dnvm list //列出所有已安裝的DNX版本 dnvm alias //列出所有定義了別名的DNX版本 dnvm alias <alias> // 顯示定義了別名的DNX名稱 dnvm alias <alias> <semver> [-x86][-x64] [-svr50][-svrc50] //給指定的DNX版本設(shè)置別名
管理程序集的dnu命令和feed源配置
通過dnu命令進行包管理的時候,通常使用如下命令:
dnu restore
:查詢程序的所有依賴包,并將其全部下載到packages目錄,該命令會下載整個依賴包以及這些依賴包所依賴的其它依賴包。
dun install <package id>
:該install命令用于下載指定的程序包并添加到程序中。
dun publish
:該命令會將你的程序打包到一個可以運行的自包含目錄中。其會創(chuàng)建如下目錄結(jié)構(gòu):
output/ output/packages outpot/appName output/commandName.cmd
1.packages
目錄包含所有應(yīng)用程序需要的程序包。
2.appName
目錄包含所有應(yīng)用程序的代碼,如果引用了其它項目,則在引用的其它項目也會創(chuàng)建各自項目的同級目錄,即生成的目錄會和AppName同級。
3.publish
命令,會將project.json中的commands節(jié)點中的各種命令,分別生成響應(yīng)的命令行文件,如commands里的web命令,我們就可以通過dnx web
(格式:dnx <command>
)開運行它。
由于dnu在內(nèi)部使用了Nuget命令,進行程序包的管理,所以使用的時候要正確配置Nuget的feed源,目前ASP.NET 5相關(guān)的包都在myget feed上,所以我們需要添加這個feed才能正常運行。這些配置信息在Windows下的%AppData%\NuGet\NuGet.config
(或者*nix下Mono使用的~/.config/NuGet/NuGet.config
)文件中進行管理。示例如下:
<?xml version="1.0" encoding="utf-8"?> <configuration> <packageSources> <add key="AspNetVNext" value="https://www.myget.org/F/aspnetvnext/api/v2/" /> <add key="nuget.org" value="https://www.nuget.org/api/v2/" /> </packageSources> <disabledPackageSources /> <activePackageSource> <add key="nuget.org" value="https://www.nuget.org/api/v2/" /> </activePackageSource> </configuration>
在VS2015下,則可以直接通過Tools--> Options--> Nuget Package Manager--> Package Sources來設(shè)置,示例如下圖:
另外需要注意一下,上述feed的地址是asp.net5的每日構(gòu)建版本,如果你想使用穩(wěn)定的里程碑版(如1.0.0_alpha4),則需要使用如下地址https://www.myget.org/F/aspnetmaster/api/v2/
Web Server支持
微軟在實現(xiàn)DNX的時候提供了幾種Web服務(wù)器支持,具體分別如下:
Microsoft.AspNet.Loader.IIS (Helios)
該服務(wù)器用于在IIS上加載ASP.NET5程序,以便和IIS進程集成,同時繞過了System.Web
從而帶來性能上的提升,可以支持Windows認證、靜態(tài)文件訪問等功能。其原理是將IIS與NDX之間做一個橋接。
Microsoft.AspNet.Server.WebListener (WebListener)
該服務(wù)器通過Microsoft.AspNet.Hosting
在IIS之外加載程序、服務(wù)、work role等,它直接運行在Http.Sys核心驅(qū)動之上,僅消費少許性能,從中可以受益于端口共享,Windows認證等功能。
Microsoft.AspNet.Server.Kestrel (Kestrel)
該服務(wù)器通過Microsoft.AspNet.Server.Kestrel
在IIS之外加載運行,其設(shè)計被用于跨平臺的Web服務(wù)(Windows、Mac、Linux等等)。
參考內(nèi)容
https://github.com/aspnet/Home/wiki/DNX-structure
https://github.com/aspnet/Home/wiki/Command-Line
https://github.com/aspnet/Home/wiki/Version-Manager
https://github.com/aspnet/Home/wiki/Package-Manager
- 解讀ASP.NET 5 & MVC6系列教程(5):Configuration配置信息管理
- 解讀ASP.NET 5 & MVC6系列教程(6):Middleware詳解
- 解讀ASP.NET 5 & MVC6系列教程(7):依賴注入
- 解讀ASP.NET 5 & MVC6系列教程(8):Session與Caching
- 解讀ASP.NET 5 & MVC6系列教程(9):日志框架
- 解讀ASP.NET 5 & MVC6系列教程(10):Controller與Action
- 解讀ASP.NET 5 & MVC6系列教程(11):Routing路由
- 解讀ASP.NET 5 & MVC6系列教程(12):基于Lamda表達式的強類型Routing實現(xiàn)
- 解讀ASP.NET 5 & MVC6系列教程(13):TagHelper
- 解讀ASP.NET 5 & MVC6系列教程(14):View Component
相關(guān)文章
決定何時使用 DataGrid、DataList 或 Repeater(ASP.NET 技術(shù)文章)
決定何時使用 DataGrid、DataList 或 Repeater(ASP.NET 技術(shù)文章)...2006-10-10NopCommerce架構(gòu)分析之(七)主題Theme皮膚管理器
本文主要介紹NopCommerce的皮膚管理機制,NopCommerce提供默認的皮膚,我們也可以制作自己的皮膚,以實現(xiàn)個性化定制。2016-04-04在ASP.NET 2.0中操作數(shù)據(jù)之六十八:為DataTable添加額外的列
本文介紹并使用TableAdapter向DataTable添加新的一列的方法和步驟,任何時候只要重新運行TableAdapter設(shè)置向?qū)?,用戶所做的所有定制都要被覆蓋,為避免出現(xiàn)這種情況,我們建議直接修改存儲過程。2016-05-05解讀ASP.NET 5 & MVC6系列教程(15):MvcOptions配置
這篇文章主要介紹了ASP.NET 5 MVC6中MvcOptions配置方法,需要的朋友可以參考下2016-06-06解讀ASP.NET 5 & MVC6系列教程(17):MVC中的其他新特性
這篇文章主要介紹了ASP.NET 5中全局導(dǎo)入、獲取IP相關(guān)信息、文件上傳等其他新特性,需要的朋友可以參考下2016-06-06NopCommerce架構(gòu)分析之(四)基于路由實現(xiàn)靈活的插件機制
本文主要介紹NopCommerce中,通過注冊路由,實現(xiàn)插件的機制,同時,NopCommerce中每個插件都集成IPlugin接口,插件擁有安裝和卸載的功能。2016-04-04