如何將 Class Library 從 .NET Framework 移植到 .NET Core ?
在實務上可能遇到有些自己寫的 class library,或在 GitHub 上 class library,原本跑在 .NET Framework 上,需要自己 porting 到 .NET Core。本文實際以一個 GitHub 上的 class library 為例,一步一步從 .NET Framework 移植到 .NET Core。
Version
macOS High Sierra 10.13.3
.NET Core SDK 2.1.101
VS Code 1.21.1
User Story
Nikola Zivkovic 提供一個類神經網路的 class library:Simple Neural Network in C#,但只能跑在 .NET Framework 4.6.1。
Task
該 class library 原本只能跑在 .NET Framework,現在我們即將以此 repository 為練習,一步一步從 .NET Framework 移植到 .NET Core。
下載 Repository
1 | $ git clone https://github.com/NMZivkovic/SimpleNeuralNetworkInCSharp |
使用 git clone
將整個 repository clone 下來。
- 將整個 repository clone 下來
- 在
SimpleNeuralNetworkInCSharp
目錄下有:- NeuralNetworkCSharp.sln:整個 repository 的 solution 檔
- NeuralNetworkCSharp:class library 的 project
- NeuralNetworkCSharpTests:class library 的 unit test project
雖然我們不知道此 repository 在做什麼,不過由於它自帶 Unit Test,我們的目的就是讓所有的 Unit Test 在 .NET Core 下都
綠燈
通過測試
重建 NeuralNetworkCSharp
因為 .NET Core 對 csproj
的 XML 格式有改,我們就不直接從 .NET Framework 的 csproj
升級上來,而是選擇建立新的 csproj
,再將所有 C# 檔案複製過來。
建立 MyClassLib
1 | $ dotnet new classlib -o MyClassLib |
使用 dotnet new classlib
建立新的 class library 專案。
- 輸入
dotnet new classlib -o MyClassLib
建立MyClassLib
專案。
複製 cs 檔案
將原來 NeuralNetworkCSharp
專案下的檔案複製到 MyClassLib
,除了 csproj
不要複製外,其他檔案全部複製。
- 將複製的檔案貼到
MyClassLib
目錄下 - 將原本的
Class1.cs
刪除
編譯專案
1 | ~/MyClassLib $ dotnet build |
使用 dotnet build
編譯 MyClassLib
。
- 輸入
dotnet build
編譯專案 - 出現
Duplicate attribute
錯誤
原本
Properties/Assembly.Info
的一些 attribute 設定,目前已經由 .NET Core 自行設定,因此才會出現 duplicate
Properties/AssemblyInfo.cs
1 | using System.Reflection; |
將其他 assembly
全部刪除,只留下 InternalsVisibleTo()
,並改成 MyTest
。
因為
MyClassLib
的一些 class 使用了internal properties
,根據 C# 規定,只有相同 assembly 才能存取internal
,但MyTest
因為不同 assembly,會造成單元測試失敗,故特別設定InternalsVisibleTo()
,讓MyTest
可以存取MyClassLib
的internal properties
- 重新輸入
dotnet build
編譯 - 編譯成功
重建 NeuralNetworkCSharpTests
將使用類似 TDD 方式,依照錯誤訊息逐一解決。
建立 MyTest
1 | $ dotnet new mstest -o MyTest |
使用 dotnet new mstest
建立新的 Unit Test 專案。
- 輸入
dotnet new mstest -o MyTest
建立MyTest
專案。
複製 cs 檔案
將原來 NeuralNetworkCSharpTests
專案下的檔案複製到 MyTest
,除了 csproj
不要複製外,其他檔案全部複製。
- 將複製的檔案貼到
MyTest
目錄下 - 將原本的
UnitTest1.cs
刪除
執行單元測試
1 | ~/MyTest $ dotnet test |
使用 dotnet test
執行單元測試。
- 輸入
dotnet test
執行單元測試 - 一樣出現
Duplicate attribute
錯誤
將 Properties/AssemblyInfo.cs
所有內容刪除。
- 在次執行
dotnet test
- 出現找不到
Moq
namespace 錯誤訊息
Moq
為 .NET 著名的 Mock package,需另外安裝
安裝 Package
在 NuGet 找的到 Moq,也有 .NET Core 版本。
1 | ~/MyTest $ dotnet add package moq |
使用 dotnet add package
安裝 Moq。
- 輸入
dotnet add package moq
安裝 Moq - 按
Restore
執行dotnet restore
- 在次執行
dotnet test
- 出現找不到
NeuralNetworkCSharp
namespace 錯誤訊息
MyTest
要測試MyClassLib
,但目前尚未對MyClassLib
加入 project reference
加入 Project Reference
1 | ~/MyTest $ dotnet add reference ../MyClassLib/MyClassLib.csproj |
使用 dotnet add reference
將 MyClassLib
加入 project reference。
- 輸入
dotnet add reference ../MyClassLib/MyClassLib.csproj
對MyClassLib
加入 project reference
- 再次輸入
dotnet test
- 通過 24 個單元測試
其中一個單元測試 skipped,是因為 test code 自己下 [igonre] 不測試,與我們無關
如此我們就順利將 Simple Neural Network in C# 由 .NET Framework 移植到 .NET Core 了。
Summary
要將 .NET Framework 的 class library 移植到 .NET Core,會有以下步驟:
- 建立新 project
- 將
*.cs
複製過來 dotnet build
會有錯誤訊息- 將
AssemblyInfo.cs
的 attribute 拿掉 - 安裝缺少的 package
- 新增必要的 project reference
- 將
- 直到
dotnet test
通過全部測試案例
Conclusion
- 並不是所有 .NET Framework 的 class library 都能移植到 .NET Core,因為目前 .NET Core 只實做了約一半的 .NET Framework API,且不是所有的 package 都有 .NET Core 版本
- 類似 TDD 方式,先執行
dotnet build
與dotnet test
,由解決錯誤訊息而逐步完成移植 - 實務上建議先對原本的 class library 補上 Unit Test,再以移植後 Unit Test 全部
綠燈
作為移植成功的依據
Sample Code
完整的範例可以在我的 GitHub 上找到