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

歡迎訪問 生活随笔!

生活随笔

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

asp.net

深入理解.NET Core的基元: deps.json, runtimeconfig.json, dll文件

發布時間:2023/12/4 asp.net 32 豆豆
生活随笔 收集整理的這篇文章主要介紹了 深入理解.NET Core的基元: deps.json, runtimeconfig.json, dll文件 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

原文鏈接: Deep-dive into .NET Core primitives: deps.json, runtimeconfig.json, and dll's作者: Nate McMaster

C#編譯器(The C# Compiler)

C#的編譯器可以將cs文件轉換為dll文件, 即程序集文件。程序集文件是一個便攜的可執行格式文件, 借助.NET Core,它可以運行在Windows, MacOS和Linux系統中。

在Windows系統中, .NET Core的編譯器文件csc.dll存放在以下目錄中

C:\Program Files\dotnet\sdk\[.NET Core 版本號]\Roslyn\bincore

筆者使用了2.1.400版本,所以編譯器存放目錄是C:\Program Files\dotnet\sdk\2.1.400\Roslyn\bincore

.NET Core編譯器文件 csc.dll也是一個.NET Core應用程序,所以你可以使用 dotnet命令直接執行編譯器

C:\test>dotnet C:\Program Files\dotnet\sdk\2.1.400\Roslyn\bincore\csc.dll --help

下面我們嘗試手動編譯一個cs文件。 首先我們先創建一個 Program.cs文件,內容如下:

/* Program.cs */ class Program { static void Main(string[] args) => System.Console.WriteLine("Hello World!"); }

然后我們使用命令行命令將其編譯

C:\test>dotnet "C:\Program Files\dotnet\sdk\2.1.400\Roslyn\bincore\csc.dll" -reference:"C:\Program Files\dotnet\sdk\NuGetFallbackFolder\microsoft.netcore.app\2.1.0\ref\netcoreapp2.1\System.Runtime.dll" -reference:"C:\Program Files\dotnet\sdk\NuGetFallbackFolder\microsoft.netcore.app\2.1.0\ref\netcoreapp2.1\System.Console.dll" -out:Program.dll Program.cs

參數說明

  • "C:\Program Files\dotnet\sdk\2.1.400\Roslyn\bincore\csc.dll"是編譯器所在的路徑

  • -reference參數表示編譯中需要引用的dll, 該參數可以指定多個dll , 例子中我們引用了System.Runtime.dll和System.Console.dll

  • -out參數表示編譯生成的dll路徑

  • Program.cs表示編譯的源文件地址

Program.cs編譯成功, Program.dll生成完畢。

runtimeconfig.json

對于.NET Core應用程序來說 runtimeconfig.json是不可或缺的。它是用來配置運行時的。

如果缺少了這個文件,運行dll文件的時候會產生以下異常。

C:\test>dotnet Program.dll A fatal error was encountered. The library 'hostpolicy.dll' required to execute the application was not found in '........'

這句話的意思是.NET Core缺少指定組件來運行程序。Program.runtimeconfig.json, 其內容如下

{ "runtimeOptions": { "framework": { "name": "Microsoft.NETCore.App", "version": "2.1.2" } } }

這里的配置dotnet命令將使用 Microsoft.NETCore.App作為共享框架(Shared Framework)。當dotnet命令運行的時候,它會去runtimeconfig.json中讀取版本號,然后去 C:\ProgramFiles\dotnet\shared\\[庫名]\\[版本號]目錄下,搜索對應的dll文件

現在我們重新運行上面的命令,結果如下:

C:\test>dotnet Program.dll Hello world!

Hello World被正確輸出了。

包(Package)

包(Package)是.NET中共享代碼的一種方式。在.NET中,包的格式是nupkg, nupkg文件是一個ZIP壓縮文件, 里面包含了.NET程序集和一個包含元數據的xml文件 。

在.NET中,最著名的包是JSON.NET, 又稱Newtonsoft.Json.它提供了一個JSON序列化和反序列化的API。我們可以從NuGet.org中下載最新版本11.0.2的nupkg文件,并解壓放置在我們當前的代碼目錄的packages\Newtownsoft.Json\11.0.2子目錄下。

為了演示如何手動導入包來編譯項目, 我們修改 Program.cs, 輸出一個序列化之后的對象, 代碼如下:

class Program { static void Main(string[] args) => System.Console.WriteLine( Newtonsoft.Json.JsonConvert.SerializeObject(new { greeting = "Hello World!" })); }

然后我們使用如下命令,編譯 Program.cs

C:\test>dotnet "C:\Program Files\dotnet\sdk\2.1.400\Roslyn\bincore\csc.dll" -reference:"C:\Program Files\dotnet\sdk\NuGetFallbackFolder\microsoft.netcore.app\2.1.0\ref\netcoreapp2.1\System.Runtime.dll" -reference:"C:\Program Files\dotnet\sdk\NuGetFallbackFolder\microsoft.netcore.app\2.1.0\ref\netcoreapp2.1\System.Console.dll" -reference:"C:\Program Files\dotnet\sdk\NuGetFallbackFolder\microsoft.netcore.app\2.1.0\ref\netcoreapp2.1\System.Collections.dll" -reference:.\packages\Newtonsoft.Json\11.0.2\lib\netstandard1.3\Newtonsoft.Json.dll -out:Program.dll Program.cs

這里為什么要引入 System.Collections.dll呢?new{greeting="Hello World!"}, 對于匿名類型, C#編譯器會為其生成一個 .Equals的方法, 這個方法調用了定義在 System.Collections.dll中 的 System.Collections.Generic.EqualityComparer方法

編譯成功,但是會出現一些警告(Warning)

Program.cs(4,35): warning CS1701: Assuming assembly reference 'System.Runtime, Version=4.0.20.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a' used by 'Newtonsoft.Json' matches identity 'System.Runtime, Version=4.2.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a' of 'System.Runtime', you may need to supply runtime policy

這意味著.Newtonsoft.Json的作者創建 Newtonsoft.Json.dll時,是使用4.0.20.0的 System.Runtime程序集, 但是系統當前使用的 System.Runtime程序集是4.2.0.0版本的。編譯器警告你4.0.20.0和4.2.0.0版本可以有很大的差異。不過幸運的是,這些差異都是向后兼容的(all backwards comptible), 所以 Newtonsoft.Json.dll可以正常工作。如果想去除這個警告,我們可以使用 -nowarn:CS1701

C:\test>dotnet "C:\Program Files\dotnet\sdk\2.1.400\Roslyn\bincore\csc.dll" -reference:"C:\Program Files\dotnet\sdk\NuGetFallbackFolder\microsoft.netcore.app\2.1.0\ref\netcoreapp2.1\System.Runtime.dll" -reference:"C:\Program Files\dotnet\sdk\NuGetFallbackFolder\microsoft.netcore.app\2.1.0\ref\netcoreapp2.1\System.Console.dll" -reference:"C:\Program Files\dotnet\sdk\NuGetFallbackFolder\microsoft.netcore.app\2.1.0\ref\netcoreapp2.1\System.Collections.dll" -reference:.\packages\Newtonsoft.Json\11.0.2\lib\netstandard1.3\Newtonsoft.Json.dll -nowarn:CS1701 -out:Program.dll Program.cs

動態鏈接(Dynamic Link)

在上一步中,我們編譯了一個引用了 Newtonsoft.Json.dll的.NET Core程序,在引用 Newtonsoft.Json.dll之前,代碼可以正常運行,但是引用 Newtownsoft.Json.dll之后,程序運行失敗。

C:\test> dotnet Program.dll Unhandled Exception: System.IO.FileNotFoundException: Could not load file or assembly 'Newtonsoft.Json, Version=10.0.0.0, Culture=neutral, PublicKeyToken=30ad4fe6b2a6aeed'. The system cannot find the file specified.

.NET是一個動態鏈接的運行時。編譯器會為 Program.dll程序集添加 Newtonsoft.Json.dll的引用,但是不會復制它的代碼。.NET Core運行時期望在 Program.dll運行的時候,動態查找并加載一個 Newtonsoft.Json.dll文件。這一點對于 System.Runtime.dll, System.Console.dll以及其他 System.*的程序集也是一樣。

.NET Core可以配置查找 Newtonsoft.Json.dll文件的目錄范圍,這里我們先簡單的將 Newtownsoft.Json.dll拷貝到與 Program.dll相同的目錄中, 然后重新運行 Program.dll

C:\test>copy .\packages\Newtonsoft.Json\11.0.2\lib\netstandard1.3\Newtonsoft.Json.dll Newtonsoft.Json.dll C:\test>dotnet Program.dll {"greeting":"Hello World!"}

我們預期的結果出現了。

注意:這里不需要拷貝System.Runtime.dll和System.Console.dll, 原因是他們存在于Microsoft.NETCore.App共享框架中,我們已經在runtimeconfig.json中配置過了。

deps.json

正如上一節所說的.NET Core可以配置查找動態鏈接程序集的位置。 這些位置包括:

  • 應用程序根目錄(這個不需要配置)

  • 包緩存目錄

  • 優化過的的包緩存或者運行時包商店

  • 服務索引

  • 共享框架(配置在runtimeocnfig.json中)

deps.json是一個記錄.NET Core中依賴清單的文件。它可以用來配置動態鏈接的程序集。

deps.json文件中定義了動態鏈接的依賴列表。通常這個文件在Visual Studio中是自動生成,而且在生產環境中也會非常的大。但是它確實是一個純文本文件,所以我們可以使用任何編輯器編寫它。

下面我們手動添加一個 Program.deps.json, 代碼如下:

{ "runtimeTarget": { "name": ".NETCoreApp,Version=v2.1" }, "targets": { ".NETCoreApp,Version=v2.1": { "Newtonsoft.Json/11.0.2": { "runtime": { "lib/netstandard1.3/Newtonsoft.Json.dll": {} } } } }, "libraries": { "Newtonsoft.Json/11.0.2": { "type": "package", "serviceable": false, "sha512": "" } } }

現在我們刪除之前拷貝過來的 Newtonsoft.Json.dll, 然后重新運行 Program.dll

C:\test>del Newtonsoft.Json.dll C:\test>dotnet Program.dll Error: An assembly specified in the application dependencies manifest (Program.deps.json) was not found: package: 'Newtonsoft.Json', version: '11.0.2' path: 'lib/netstandard1.3/Newtonsoft.Json.dll'

由此可見,盡管我們添加了 deps.json, .NET Core依然需要一些其他的信息來探測 deps.json中定義的動態程序集。 這里有3種方式來設置,你可以選中一行任意一種方式設置搜索動態鏈接庫的目錄路徑,修改之后, {"greeting":"Hello World!"}就會正常輸出出來。

*.runtimeconfig.dev.json

這種一種方式是最佳的實現方式.我們可以添加一個 Program.runtimeconfig.dev.json,并在其中添加動態鏈接搜索目錄字段 additionalProbingPaths

{ "runtimeOptions": { "additionalProbingPaths": [ "/Users/nmcmaster/code/packages/" ] } }

注解:這里的配置類似于Transformed Config, 如果指定當前的環境是dev,它就會讀取Program.runtimeconfig.json, 并將Program.runtimeconfig.dev.json的內容覆蓋進去

命令行

我們還是可以使用 dotnetexec命令并指定 --additionalprobingpath參數來配置檢索的目錄。

C:\test> dotnet exec --additionalprobingpath ./packages/ Program.dll

*.runtimeconfig.json

當然你也可以直接在 *.runtimeconfig.json中添加 additionalProbingPaths字段

{ "runtimeOptions": { "framework": { "name": "Microsoft.NETCore.App", "version": "2.1.2" }, "additionalProbingPaths": [ "./packages/" ] } }

參考文獻

  • Specs on runtimeconfig.json and deps.json

  • Packages, metapackages and frameworks

  • .NET Core application deployment

  • The implementation of the shared framework lookup

總結

以上是生活随笔為你收集整理的深入理解.NET Core的基元: deps.json, runtimeconfig.json, dll文件的全部內容,希望文章能夠幫你解決所遇到的問題。

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