理解ASP.NET 5運行時命令:DNVM, DNX, 和DNU

jopen 9年前發布 | 29K 次閱讀 ASP.NET


ASP.NET 5 引入了一個新型的運行時,讓我們可以現場交付模式組合式構建應用程序,而不依賴于宿主機上的.NET框架。這種新模式為我們提供了命令行工具(DNVM、 DNX、DNU)用于管理我們的.net 版本,依賴的庫和運行環境,我們可以不需要Visual Studio,只需要一個文本編輯器和命令行就可以開發一個應用程序。

了解.NET 版本管理器 (DNVM) 之間 ,.NET 執行環境 (DNX) 和.NET 開發實用程序 (DNU) 之間的關系是開發 ASP.NET 5的根本。在這篇文章我們將看看在CentOS安裝并使用 DNVM,DNX 和 DNU ,從命令行和文本編輯器開發一個簡單應用程序,如果你使用docker,這些命令和docker還真是很像。

DNVM .NET Version Manager ):由于要實現跨平臺的目錄,微軟提供了 DNVM 功能, DNVM ASP.NET 最底層的內容,它是一組 Powershell 腳本,用于啟動指定版本的 ASP.NET 運行環境,并且可以在同一臺機器的同一時間點上通過使用 Nuget 工具來管理各種版本的 ASP.NET 運行環境( DNX ),以及進行相應的升級操作。

DNX .NET Execution Environment ): DNX ASP.NET 程序的運行環境,用于啟動并運行 ASP.NET 程序。該運行環境包括了編譯系統、 SDK 工具集、 Native CLR 宿主環境。可以使用 DNVM 管理各種版本的 DNX ,如 dnvm list 命令可以列出所有可用的 DNX 環境,而 dnvm install 1.0.0-beta4 則可以將指定版本的 DNX 安裝到 .dnx 文件夾,你可以在 %USERPROFILE%\.dnx\runtimes 目錄下找到已安裝所有版本的 DNX 。不同的操作系統有不同的 DNX 版本。

dnx.exe :dnx.exe 是用于啟動自宿主環境( Self-Hosting )的命令行工具,在使用命令行代碼進行自宿主環境啟動程序時, dnx 負責查找并調用 CLR Native Host dnx 命令是整個運行環境的入口點,你可以使用 dnx run 來啟動程序。

dnu DNX Utility : 是一個命令行的包管理器,包含在 DNX 內,所以只要安裝了 DNX ,就可以使用 dnu 命令, 其可以用于恢復程序包、安裝程序包、部署程序包等等,比如把 project.json 里自定義的程序集自動下載下來進行使用。

DNX 架構及運行原理

DNX ASP.NET 程序運行的核心,其遵循如下兩個準則:

  1. DNX 應該是自包含的, DNX 在解析完應用程序依賴樹以后才能知道要使用哪個 Core CLR 包,所以在得到解析樹之前, DNX 是無法加載任何 CLR 的,但 Roslyn 編譯器除外。
  2. 依賴注入( Dependency Injection ,簡稱 DI )貫穿著整個系統棧, DI DNX 的一個核心部分,所有 DNX 上的類庫都構建在 DI 之上。

DNX 執行環境的分層架構如下:

理解ASP.NET 5運行時命令:DNVM, DNX, 和DNU

Layer 0:Native Process

該層的功能非常簡單,主要就是用于查找并調用 Layer 1 里的 CLR Native Host ,并將系統相關的參數傳遞給 native host ,以便后續使用。目前 Windows 下使用 DNX.exe 來處理這個事情,而 IIS 也提供了一個中介(網站 bin 目錄下提供一個 AspNet.Loader.dll )可以將請求轉發給 Native Host ;而 Linux Mac 則通過其相應版本的 dnx 來支持這項功能。

DNX 用法:

dnx . exe -- lib {paths} -- appbase {path} [ ProgramName ]

--lib {paths} :程序集 dll 的保存地址(一般是引用的第三方程序集和項目預編譯程序集),該地址是 Layer 2 層的托管代碼入口點可以加載程序集的地方。

--appbase {path} :程序保存的目錄,默認為 %CD%

[ProgramName] :程序名稱,該程序所在的程序集(或者是含有 Programe::Main dll )保存在 --lib 路徑下,默認值是 appbase\project.json 里的 name 。大多數情況下,該名稱都是包含著加載鏈的程序宿主( Microsoft.Net.ApplicationHost )。但是,如果你的程序包含了入口點( Main 方法),并被編譯到 --lib 目錄下的話,你就可以使用該程序集的名稱作為 [ProgramName] ,這種方式將完全忽略加載鏈并直接啟動你的程序。

Layer 1 : CLR Native Host

這一層的內容依賴于你所選擇呢 CLR 版本,該層有如下兩個職責:

  1. 啟動 CLR ,啟動哪個 CLR 取決于你選擇的 CLR 版本。如果是 Core CLR ,該層會加載 coreclr.dll ,配置并啟動運行環境,然后創建應用程序域( AppDomain ),以便運行所有的托管代碼。
  2. 調用托管代碼的入口點( Layer 2 ),一旦 Native Host 的入口點返回了該線程,就會把 CLR 的線程清理干凈并關閉,比如,卸載應用程序域( AppDomain )并停止運行環境。

Layer 2 Managed Entry Point

Layer 2 層(托管代碼入口)是編寫托管代碼的第一層,其職責如下:

  1. 創建 LoaderContainer (其包含需要的 ILoaders ), ILoader 負責根據程序集的名稱來加載程序集。 CLR 需要一個程序集的話, LoaderContainer 就會使用其 ILoader 來解析所需要的程序集。
  2. --lib 的路徑目錄下,用根 ILoader 來加載程序集,并解析其依賴。
  3. 調用程序的主入口點。

Layer 3 Application host/Application

如果開發人員將整個程序編譯成程序集放在 libpath 目錄下,那該層就是你的應用程序了。使用的時候,將含有程序入口點的程序集名稱作為 [ProgramName] 的參數傳入即可, Layer 2 層會直接調用該程序集。

不過,一般其它情況下,都會使用一個應用程序宿主( Application host )來解析程序的依賴內容并啟動運行程序。 Microsoft.Net.ApplicationHost 是運行環境提供的應用程序宿主,并擁有如下職責:

  1. 解析 project.json 里定義的各種依賴程序集。
  2. 將一個 ILoader 添加到 LoaderContainer ,以便從各種地方(如源代碼、 NuGet Roslyn 等)加載相應的程序集。
  3. 調用程序集的入口點,將其作為下一個參數,傳遞給 DNX.exe

Layer 4 Application

這一層,就是開發人員開發的程序,其運行在應用程序宿主之上。

環境配置:

要對 ASP.NET 5 程序的運行環境 DNX 進行配置,首先需要安裝并配置 DNVM CentOS Linux 系統上需要先安裝 Mono ,可以參照文章 CentOS 7 上部署 Mono 4 Jexus 5.6 。然后運行下面命令

curl -sSL https://raw.githubusercontent. com /aspnet/Home/master/dnvminstall. sh | sh && source ~/.dnx/dnvm/dnvm. sh

[root@Mono ~]# curl -sSL https://raw.githubusercontent.com/aspnet/Home/dev/dnvminstall.sh | DNX_BRANCH=dev sh && source ~/.dnx/dnvm/dnvm.sh

Downloading dnvm as script to '/root/.dnx/dnvm'

Appending source string to /root/.bash_profile

Type 'source /root/.dnx/dnvm/dnvm.sh' to start using dnvm

運行命令 dnvm

理解ASP.NET 5運行時命令:DNVM, DNX, 和DNU

上述 DNVM 安裝以后,系統會將 dnvm 文件復制到 /root/.dnvm 目錄,并將 /root/.dnvm 目錄添加到環境變量中,以便全局都可以使用。注意:這里只是安裝了 DNVM ,并沒有安裝任何版本的 DNX ,要安裝 DNX 的話,可以通過運行 dnvm dnvm help 來查找相關的命令,具體命令如下:

dnvm upgrade [-x86][-x64] [-svr50][-svrc50] [-g|-global] [-proxy < ADDRESS > ]

  1. feed 源安裝最新版的 DNX
  2. 為已安裝的 DNX 設置一個默認( default )別名
  3. DNX bin 添加的用戶 PATH 環境變量中
  4. -g|-global 在全局內進行安裝(其它用戶也可以使用)
  5. -f|-force 強制更新成最新版(即便最新版已經安裝過了)
  6. -proxy 訪問遠程服務器的時候使用特定的地址作為代理

dnvm install < semver > | < alias > | < nupkg > |latest [-x86][-x64] [-svr50][-svrc50] [-a|-alias < alias > ] [-g|-global] [-f|-force]

  1. | feed 源安裝指定的 DNX
  2. 從本地文件系統安裝指定的 DNX
  3. latest feed 源安裝最新版的 DNX
  4. DNX bin 添加到當前命令行的 path 環境變量中
  5. -p|-persistent DNX bin 添加到系統 PATH 環境變量中
  6. -a|-alias 對指定安裝的 DNX 設置別名
  7. -g|-global 在全局內進行安裝
  8. -f|-force 強制安裝指定的 DNX (即便該版本已經安裝過了)

dnvm use < semver > | < alias > |none [-x86][-x64] [-svr50][-svrc50] [-p|-persistent] [-g|-global]

  1. | DNX bin 添加到當前命令行的 path 環境變量中
  2. none DNX bin 從當前命令行的 path 環境變量中刪除
  3. -p|-persistent DNX bin 添加到系統 PATH 環境變量中
  4. -g|-global 組合使用 -p 將用戶 PATH 修改成系統 PATH

dnvm list // 列出所有已安裝的 DNX 版本

dnvm alias // 列出所有定義了別名的 DNX 版本

dnvm alias < alias > // 顯示定義了別名的 DNX 名稱

dnvm alias < alias > < semver > [-x86][-x64] [-svr50][-svrc50] // 給指定的 DNX 版本設置別名

理解ASP.NET 5運行時命令:DNVM, DNX, 和DNU

管理程序集的 dnu 命令和 feed 源配置

通過dnu命令進行包管理的時候,通常使用如下命令:

dnu restore:查詢程序的所有依賴包,并將其全部下載到packages目錄,該命令會下載整個依賴包以及這些依賴包所依賴的其它依賴包。

dun install <package id>:該install命令用于下載指定的程序包并添加到程序中。

dun publish:該命令會將你的程序打包到一個可以運行的自包含目錄中。其會創建如下目錄結構:

output/

output/packages

outpot/appName

output/commandName.cmd

packages目錄包含所有應用程序需要的程序包。

appName目錄包含所有應用程序的代碼,如果引用了其它項目,則在引用的其它項目也會創建各自項目的同級目錄,即生成的目錄會和AppName同級。

publish命令,會將project.json中的commands節點中的各種命令,分別生成響應的命令行文件,如commands里的web命令,我們就可以通過dnx web(格式:dnx <command>)開運行它。

由于dnu在內部使用了Nuget命令,進行程序包的管理,所以使用的時候要正確配置Nuget的feed源,目前ASP.NET 5相關的包都在myget feed上,所以我們需要添加這個feed才能正常運行。這些配置信息在*nix下Mono使用的~/.config/NuGet /NuGet.config文件中進行管理,示例如下:

理解ASP.NET 5運行時命令:DNVM, DNX, 和DNU

從命令行開始構建一個控制臺程序

我們使用 vim dnx/dnu 命令行構建一個簡單的程序,創建一個目錄 dnx_demo, 在目錄下創建一個 project.json 文件,包含下面內容:

{

"version": "1.0.0-*",

"description": "geffzhang demo project",

"commands": {

"runme": "dnx_demo"

},

"frameworks": {

"dnx451": { },

"dnxcore50": {

"dependencies": {

"System.Console": "4.0.0-beta-22816",

"Microsoft.CSharp": "4.0.0-beta-22816"

}

}

}

}

上面我們定義了一個命令"runme",它指向的是工程名稱:dnx_demo。我們可以通過命令行使用dnx運行我們的項目,我們的項目指向傳 統的.NET Framework (dnx451) 和 .NET Core (dnxcore50),所以我們可以用dnx和.net fx運行。

然后在創建一個 Program.cs文件,內容如下:

using System;

namespace dnx_demo

{

public class Program

{

public void Main(string[] args)

{

Console.WriteLine("No Visual Studio Here!!");

Console.Read();

}

}

}

保存后,我們先運行命令 dnu restore ,將我們依賴的程序包下載到 package 目錄。

理解ASP.NET 5運行時命令:DNVM, DNX, 和DNU

目前我們運行的程序還僅僅是一個非常簡單的控制臺程序,還沒有包括EF, SignalR, Identity等復雜組件,但從整個部署過程中,我們可以感覺到其實差距已經很小. 首先運行和部署環境DNVM和dnu, dnx命令和VS 2015的環境是一致的,而且組件包都是從Nuget上獲取,這和標準的Windows開發環境并沒有太大區別。

 本文由用戶 jopen 自行上傳分享,僅供網友學習交流。所有權歸原作者,若您的權利被侵害,請聯系管理員。
 轉載本站原創文章,請注明出處,并保留原始鏈接、圖片水印。
 本站是一個以用戶分享為主的開源技術平臺,歡迎各類分享!