從 .NET Framework 升級到 .NET Core/6/8/10,我最有感的開發體驗提升是 .csproj 檔的簡化!

傳統 .csproj 必須正向表列所有專案包含的檔案項目,不管 .aspx/.cs/.js/.css/.png/.jpg... 要逐一列舉才會納入專案範圍,出現在發佈結果。

2016 推出的 .NET Core 改採所謂 SDK 風格專案 (SDK-Style Project),特徵是 .csproj 的 Project XML 元素有 Sdk="Micrsofot.NET.Sdk" 宣告套用的 SDK 類型,而最大革新是改為隱式包含(Wildcard Inclusion),不再需要列舉專案檔案,專案預設會自動納入必要項目(Compile 類:**/*.cs、EmbeddedResource 類:**/*.resx、None:其他一般檔案,並排除 bin、obj 等目錄),開發者可依需要額外加入或排除參考,比傳統做法省事且簡潔許多。

比較二者差異:

項目傳統 .csprojSDK Style .csproj
根節點ToolsVersion、XML namespace、明確 imports<Project Sdk="Microsoft.NET.Sdk">
目標框架<TargetFrameworkVersion>v4.8</TargetFrameworkVersion><TargetFramework>net48</TargetFramework>
原始碼每個 .cs 都要有 <Compile Include>預設自動包含 **/*.cs
資源及一般檔案通常逐一列出透過 glob 自動包含
MSBuild targets明確 <Import>SDK 自動匯入 Sdk.props 與 Sdk.targets
組件資訊通常放在 Properties/AssemblyInfo.cs預設由 SDK 自動產生
NuGet常使用 packages.config 和 HintPath通常使用 <PackageReference>
專案 GUID一般必須保留新式專案通常不需要
多目標框架設定繁複可使用 <TargetFrameworks>
手動維護用 Visual Studio 操作 OK,手動新增、刪除檔案易出現衝突檔案系統通常就是專案內容

傳統格式範例:

<Project ToolsVersion="12.0"
         DefaultTargets="Build"
         xmlns="http://schemas.microsoft.com/developer/msbuild/2003">

  <PropertyGroup>
    <TargetFrameworkVersion>v4.8</TargetFrameworkVersion>
  </PropertyGroup>

  <ItemGroup>
    <Compile Include="Controllers\HomeController.cs" />
  </ItemGroup>

  <Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" />
</Project>

SDK Style 格式範例

<Project Sdk="Microsoft.NET.Sdk">
  <PropertyGroup>
    <TargetFramework>net48</TargetFramework>
  </PropertyGroup>
</Project>

SDK 風格 .csproj 具備以下優點:

  1. 不需列舉專案檔案項目,專案檔大幅縮小且變簡潔
  2. 會依據 SDK 決定編譯行為,不需額外引用 Targets
  3. 增刪專案項目時不用同步修改 .csproj
  4. NuGet 參照清單包含在 .csproj 裡 (不再需要 packages.config)
  5. 支援多目標框架建置 <TargetFrameworks>net48;netstandard2.0</TargetFrameworks> (過去得建多個 .csproj 共用檔案)

由上面出現的 net48,大家可能已經發現了,是的,.NET Framework 專案也可以改用 SDK 風格 csproj! 從 VS2017 開始便支援。

但別高興太早,.NET Framework 專案的 .csproj 是可以轉換成 SDK Style 專案但有限制,主要取決專案是否依賴 Visual Studio 專案功能、Designer 或特殊發佈的 Targets。

不同專案類型的轉成 SDK Style .csproj 的可行性如下:

.NET Framework 專案類型可轉換性說明
Class Library適合最容易轉換,並能輕鬆實現多目標
Console Application適合選用 Microsoft.NET.Sdk
Windows Service可行本質為 EXE;安裝流程需另外驗證
WinForms可行選用 Microsoft.NET.Sdk 並啟用 UseWindowsForms
WPF可行選用 Microsoft.NET.Sdk 並啟用 UseWPF
單元測試專案可行需改用對應的 Test SDK/adapter
WCF Client/一般 WCF Library可行Generated Proxy、設定檔及設計工具需驗證
WCF Service Application有條件若依賴舊式 Web Application Hosting,問題與 ASP.NET 相同
ASP.NET MVC 5/Web API 2 Web Application可能但困難能客製化,但無法簡單轉換
ASP.NET Web Forms Web Application可能但困難高度依賴舊 Web 專案系統
ASP.NET Web Site不支援Web Site 無 .csproj,須先改成 Web Application
VSTO/Office Add-in不適合依賴 VSTO 專案系統及專用 Targets
Workflow Foundation Library有條件編譯可能可行,但 Designer/Tooling 常有限制
SharePoint 舊式專案不適合依賴專用 Visual Studio Tooling
Portable Class Library應遷移建議改成 .NET Standard SDK Style

評估了一下,手邊的古蹟專案以 ASP.NET MVC 及 ASP.NET Web Site 為大宗,應無緣享用。

SDK-style .csproj files greatly simplify .NET projects with implicit file inclusion, cleaner NuGet references, and easier multi-targeting. While .NET Framework projects can sometimes be converted, support varies by project type, with classic ASP.NET and tooling-heavy projects remaining difficult or unsuitable.


Comments

# by Vinix

手邊正在維護的也是ASP.Net 4.8 Web Forms Web Application,以前評估轉.NET最後也是因為太麻煩所以放棄。

# by Player

專案檔以往不是都會隨著使用的IDE版本 提示是否升級的嗎? 為了避免轉檔失敗 還會幫你複製一份備份的資料夾? 與提供升級成功與否的明細報告 此外,.NET Framework的ASP.NET WebForms想轉 .NET的ASP. NET Core根本上寫法就不一樣了吧 這不是你只改個專案檔使用的SDK版本就能搞定的 只有ASP.NET MVC才比較接近ASP.NET Core MVC才有移植的可能

# by 訪客

那sln 可以嗎

# by Jeffrey

to Player, 這裡說的轉換是 .csproj 改用 SDK Style 版本,.NET Framework 版本不變,沒有要升級 .NET 版本或專案架構。如文章所說,若是 Class Library 很適合切換,Web Form 跟 IDE 綁太緊,很難。

# by SHIH HUNG YANG

學到新了新知識,但目前已經在評估改用 VS CODE + AI 撰寫除錯,在開 VS 2010、 2017 IDE 跑測試,或乾脆直接裝 IIS 測試.. 複雜的程式碼管理與 30年的技術債已經想放推了...

Post a comment