用 VSCode 寫 .NET 6 程式好一陣子,都還是單一專案範例或小工具,最近要寫個 .NET Standard 2.0 程式庫讓 .NET 4.6.1+ 跟 .NET 6 專案共用,第一次嘗試在 VSCode 處理有兩個專案的 .sln,值得寫篇筆記。

MS Doc 有篇教學 - Tutorial: Create a .NET class library using Visual Studio Code,原則上照做即可,這裡以繁簡轉換類別程式庫為範例,打算建一個 .NET Standard 2.0 程式庫跟一個 Console 程式呼叫它做測試,步驟整理如下:

  1. 先為 .sln 建個資料夾,例如:D:\ChConvLab
  2. 開 Cmder 或 Terminal,CD D:\ChConvLab,dotnet new sln,產生 ChConvLab.sln
  3. 輸入 code . 開啟 VSCode
  4. 開啟 Terminal
  5. 建立類別程式庫專案,指定平台目標 .NET Starndard 2.0,dotnet new classlib -o ChConvUtil --framework "netstandard2.0"
    說明:繁簡轉換的核心我使用 OpenCC.NET 開源專案,背後是 OpenCC 詞庫結巴分詞
  6. 切換到 ChConvUtil 目錄
  7. dotnet add package OpenCCNet 安裝程式庫 (註:NuGet 上 OpenCC.NET 名稱被其他套件用掉了,OpenCC.NET 專案的套件名為 OpenCCNet)
  8. 撰寫 Converter.cs 類別(只簡單處理資源檔路徑及提供單純的轉換 API)
     using System;
     using System.IO;
     using OpenCCNET;
    
     namespace ChConvUtil
     {
         public class Converter
         {
             public Converter(string path = ".") {
                 var jiebaResourceDirectory = Path.Combine(path, "JiebaResource");
                 JiebaNet.Segmenter.ConfigManager.ConfigFileBaseDir = jiebaResourceDirectory;
                 ZhConverter.Initialize();
                 ZhDictionary.Initialize(
                     Path.Combine(path, "Dictionary"));
             }
             public string TWtoCN(string src) => ZhConverter.TWToHans(src, true);
             public string CNtoTW(string src) => ZhConverter.HansToTW(src, true);
         }
     }
    
  9. 切換回 ChConvLab 目錄,dotnet sln add .\ChConvUtil\ChConvUtil.csproj 將專案加入 .sln
  10. 建立測試用的 .NET 6 Console 專案:dotnet new console -o ChConvTest
  11. 加入 sln,dotnet sln add .\ChConvTest\ChConvTest.csproj
  12. https://github.com/CosineG/OpenCC.NET 下載 JiebaResource 及 Dictionary 資料夾,放到 ChConvTest 專案目錄。
  13. 讓 ChConvTest 參照 ChConvUtil 專案,dotnet add .\ChConvTest\ChConvTest.csproj reference .\ChConvUtil\ChConvUtil.csproj。
    檢視 ChConvTest.csproj,可觀察到多了 ProjectReference Include="..\ChConvUtil\ChConvUtil.csproj",執行 OpenCC.NET 需指定 JiebaResource 及 Dictionary 資料夾位置,我打算放在 .dll 同目錄,故順便修改 csproj 加上 Content Include="...\**" CopyToOutputDiretory="PreserveNewest" 指定編譯時要一併複製 JiebaResource 及 Dictionary 資料夾:
  14. 修改 Program.cs,加幾行測試程式:
    var s = "預設記憶體大小與硬碟容量";
    var resPath = 
        Path.GetDirectoryName(typeof(Program).Assembly.Location);
    var c = new ChConvUtil.Converter(resPath);
    var r = c.TWtoCN(s);
    Console.WriteLine(r);
    Console.WriteLine(c.CNtoTW(r));
    
  15. 執行 dotnet run --project .\ChConvTest\ChConvTest.csproj (在 .sln 目錄執行其中某個專案),.NET CLI 知道 ChConvTest 專案參照 ChConvUtil 專案,故會先編譯 ChConvUtil.dll,再執行 ChConvTest,順利完成繁簡轉換:(繁簡轉換結果與分詞詞庫有關,實務應用需依處理內容擴充常用詞庫及對映表,就像人工智慧程式需要訓練學習才能提高精確度)

至於我想偵錯 ChConvTest 怎麼辦?能 F11 追蹤進 ChConvUtil 嗎?

透過正確設定 launch.json 及 tasks.json,VSCode 也可以像 Visual Studio 指定 .sln 的 Start Project,從 .sln 目錄進行偵錯。但我覺得有點複雜,所以我習慣再開一個 VSCode 開啟 ChConvTest 進行偵錯,ChConvUtil 修改時會重新編譯,按 F11 也可以追進 ChConvUtil 的原始碼,完全滿足我的開發需要。

看到這裡肯定有朋友想問,何必折騰?Visual Studio 2022 難道不香嗎?

用 VSCode 寫 .NET 6 幾個月下來,可以感受到 VSCode 固然輕巧方便,開發流暢度與 Visual Studio 仍有差距,畢竟二者定位不同,VSCode 以編輯器出發,配合各式擴充套件提高開發效率,有些操作仍需借肋 CLI 指令;而 Visual Studio 是整合式開發環境,針對開發流程做過全面優化,力求用最少動作完成各項工作,爽度肯定碾壓 VSCode。這正是我遲遲還沒裝 VS2022 的原因,擔心用過就回不去了,藉此機會逼自己熟悉 VSCode 以及 .csproj、編譯、發行的細節,差不多是「把自己丟到國外幾個月,英文才會突發猛進」的概念吧,哈。

Tutorial of how to develop and test class library and console application projects in VSCode.


Comments

# by Victor Tseng

搭內使顛打已經日落了,2.0是最後一版,雖然繼續用不會爆炸,不過潮度比較低…

# by Jeffrey

to Victor,程式庫採 .NET Standard 2.0 是基於要同時支援 .NET Core/5/6 或 .NET 4.X,應與潮度無關。

# by Kevin

.NET standard 和.NET framework 是兩回事😂

# by Victor Tseng

(資訊更正,最末版 .NET Standard 是 2.1 版,內含 Span<T> 等) 微軟官方已經不會再推出新版的 .NET Standard,雖說在這邊 https://devblogs.microsoft.com/dotnet/the-future-of-net-standard/ 的指引是 To summarize: Use netstandard2.0 to share code between .NET Framework and all other platforms. Use netstandard2.1 to share code between Mono, Xamarin, and .NET Core 3.x. Use net5.0 for code sharing moving forward. 但是文中對 .NET Standard 也是嫌東嫌西 (那當初幹嘛搞這個?),個人不負責任的看法是,衝著他講的 "moving forward",隨著新開發的 app 逐漸往 .NET 6 7 8 9 10... 靠攏後,full .NET Framework 跟 .NET Standard 會逐漸式微,畢竟新的好料都不會出現在 full .NET Fx 跟 .NET Std,然後這就變成下一篇古蹟維修的題材。 拿有望取代 json.net 的 System.Text.Json (https://www.nuget.org/packages/System.Text.Json/) 6.x 版為例,他目前的 target 有 .NET 4.6.2, .NET Standard 2.0, .NET Core 3.1 跟 .NET 6,也許過幾年可以回來看看最新版本的 target 長什麼樣子。這是官方在維護的套件,而且是把 json.net 作者挖來弄的,所以我覺得他的 target 設定有一定程度的指標意義。

Post a comment