原文:https://natemcmaster.com/blog/2017/12/21/netcore-primitives/
linux上安裝dotnet參照:https://blog.csdn.net/u010476739/article/details/100144287
實驗目的:
探究與.netcore編譯和運行有關的*.deps.json, *. runtimeconfig.json,,*.dll文件
實驗環境:
- centos7.6 x 64
- dotnet-sdk-2.2.401-linux-x64.tar.gz
- dotnetsdk是按照博文.netcore入門1:linux上安裝.net core sdk 2.2(離線安裝和yum倉庫安裝)上面介紹的使用離線安裝包安裝的,安裝到了/usr/local/dotnet目錄
一、使用Roslyn編譯器第一個CS文件
1.1 在目錄/root下新建文件“Program.cs”
Program.cs:
class Programe{
public static void Main(string[] args){
System.Console.WriteLine("Hello world");
}
}
1.2 使用csc.dll編譯這個文件生成Program.dll
[root@localhost ~]# ll
總用量 8
-rw-------. 1 root root 1215 8月 29 11:28 anaconda-ks.cfg
-rw-r--r--. 1 root root 116 9月 2 15:47 Program.cs
[root@localhost ~]# dotnet /usr/local/dotnet/sdk/2.2.401/Roslyn/bincore/csc.dll -reference:/usr/local/dotnet/sdk/NuGetFallbackFolder/microsoft.netcore.app/2.2.0/ref/netcoreapp2.2/System.Runtime.dll -reference:/usr/local/dotnet/sdk/NuGetFallbackFolder/microsoft.netcore.app/2.2.0/ref/netcoreapp2.2/System.Console.dll -out:Program.dll Program.cs
Microsoft (R) Visual C# Compiler version 3.2.0-beta2-19303-01 (c9689b7a)
Copyright (C) Microsoft Corporation. All rights reserved.
[root@localhost ~]# ll
總用量 12
-rw-------. 1 root root 1215 8月 29 11:28 anaconda-ks.cfg
-rw-r--r--. 1 root root 116 9月 2 15:47 Program.cs
-rw-r--r--. 1 root root 3584 9月 2 16:14 Program.dll
1.3 運行Program.dll
命令行直接運行:dotnet Program.dll
[root@localhost ~]# dotnet Program.dll
A fatal error was encountered. The library 'libhostpolicy.so' required to execute the application was not found in '/root/'.
Failed to run as a self-contained app. If this should be a framework-dependent app, add the /root/Program.runtimeconfig.json file specifying the appropriate framework.
這裏提示的很明顯,這個dll需要使用“Program.runtimeconfig.json”文件來指定運行的框架。
新建文件/root/Program.runtimeconfig.json,內容如下:
{
"runtimeOptions": {
"framework": {
"name": "Microsoft.NETCore.App",
"version": "2.2.0"
}
}
}
再次運行:dotnet Program.dll
[root@localhost ~]# dotnet Program.dll
Hello world
這個時候正常運行了,它所依賴的System.Runtime.dll、System.Console.dll都在Program.runtimeconfig.json文件中以運行目標框架的方式指定了。
二、引用外部依賴再編譯運行
2.1 準備Newtonsoft.Json包
下載地址:https://www.nuget.org/packages/Newtonsoft.Json/12.0.2
新建文件夾/root/packages/Newtonsoft.Json/12.0.2:
[root@localhost ~]# mkdir -p ./packages/Newtonsoft.Json/12.0.2
將下載好的newtonsoft.json.12.0.2.nupkg文件解壓到/root/packages/Newtonsoft.Json/12.0.2中,解壓後的目錄爲:
2.2 修改Program.cs文件內容如下:
class Programe{
public static void Main(string[] args){
System.Console.WriteLine(Newtonsoft.Json.JsonConvert.SerializeObject(new { greeting = "Hello World!" }));
}
}
2.3 編譯Program.cs
[root@localhost ~]# dotnet /usr/local/dotnet/sdk/2.2.401/Roslyn/bincore/csc.dll -reference:/usr/local/dotnet/sdk/NuGetFallbackFolder/microsoft.netcore.app/2.2.0/ref/netcoreapp2.2/System.Runtime.dll -reference:/usr/local/dotnet/sdk/NuGetFallbackFolder/microsoft.netcore.app/2.2.0/ref/netcoreapp2.2/System.Console.dll -reference:./packages/Newtonsoft.Json/12.0.2/lib/netstandard1.3/Newtonsoft.Json.dll -reference:/usr/local/dotnet/sdk/NuGetFallbackFolder/microsoft.netcore.app/2.2.0/ref/netcoreapp2.2/System.Collections.dll -out:Program.dll Program.cs
Microsoft (R) Visual C# Compiler version 3.2.0-beta2-19303-01 (c9689b7a)
Copyright (C) Microsoft Corporation. All rights reserved.
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.1.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a' of 'System.Runtime', you may need to supply runtime policy
Program.cs(3,34): 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.1.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a' of 'System.Runtime', you may need to supply runtime policy
[root@localhost ~]#
可以看到編譯成功,後面出現的警告是因爲Newtonsoft.Json.dll的版本問題,先不用理會這個(版本兼容)。
2.4 運行Program.dll
[root@localhost ~]# dotnet Program.dll
Unhandled Exception: System.IO.FileNotFoundException: Could not load file or assembly 'Newtonsoft.Json, Version=12.0.0.0, Culture=neutral, PublicKeyToken=30ad4fe6b2a6aeed'. The system cannot find the file specified.
已放棄
可以看到,直接運行是報錯的,提示找不到Newtonsoft.Json,我們可以將Newton.Json.dll文件從引用的目錄直接拷貝到Program.dll同目錄來,然後運行:
[root@localhost ~]# dotnet Program.dll
{"greeting":"Hello World!"}
直接將外部依賴拷貝到生成的dll文件的同目錄,這種方法也是ide工具用的方法也是我們最容易理解的。
現在來看另外一種方法:
首先刪除掉同目錄的Newtonsoft.Json.dll文件
然後添加文件Program.deps.json,在這個文件中寫入依賴信息如下:
{
"runtimeTarget":{
"name":".NETCoreApp,Version=v2.2.0"
},
"targets":{
".NETCoreApp,Version=v2.2.0":{
"Newtonsoft.Json/12.0.2":{
"runtime":{
"lib/netstandard1.3/Newtonsoft.Json.dll":{}
}
}
}
},
"libraries":{
"Newtonsoft.Json/12.0.2":{
"type":"package",
"serviceable":false,
"sha512":""
}
}
}
接着修改文件Program.runtimeconfig.json,在這個文件中寫入依賴程序集的搜索路徑
{
"runtimeOptions":{
"framework":{
"name":"Microsoft.NETCore.App",
"version":"2.2.0"
},
"additionalProbingPaths":[
"./packages/"
]
}
}
最後運行如下:
[root@localhost ~]# ll
總用量 24
-rw-------. 1 root root 1215 8月 29 11:28 anaconda-ks.cfg
drwxr-xr-x. 3 root root 29 9月 2 16:33 packages
-rw-r--r--. 1 root root 181 9月 2 16:37 Program.cs
-rw-r--r--. 1 root root 460 9月 2 16:56 Program.deps.json
-rw-r--r--. 1 root root 4608 9月 2 16:40 Program.dll
-rw-r--r--. 1 root root 156 9月 2 16:56 Program.runtimeconfig.json
[root@localhost ~]# dotnet Program.dll
{"greeting":"Hello World!"}
可以看到運行成功了!