我在 GitHub .NET SDK GitHub 原始碼 : https://github.com/dotnet/sdk ,查到是由 jjonescz 提交的 commit 46ce5ca 開始。
他設計主要的邏輯
dotnet run hello.cs
,不需要 .csproj
或建立傳統專案結構。dotnet new console
預設模板,然後套用針對 file-based app 的特殊屬性:
FileBasedProgram=true
:標記此為單檔模式PublishAot=true
.cs
會被檢測是否包含 top-level statements,這些語句會被轉換為隱式 Main
。static void Main
則不視為支援情境(規格刻意限制以降低複雜度)。EnableDefaultCompileItems=false
,只將使用者指定的那個檔案加入編譯。#import ./another-file.cs
或類似 directive 方式顯式納入額外檔案。單檔模式允許在檔案頂部以「檔案層級指示(directives)」宣告專案設定,常見:
Directive | 作用 | 轉換成 MSBuild 範例 |
---|---|---|
#:sdk |
指定 SDK | <Project Sdk="Microsoft.NET.Sdk" /> |
#:property |
設定屬性 | <PropertyGroup><PublishAot>true</PublishAot></PropertyGroup> |
#:package |
加入 NuGet 套件 | <ItemGroup><PackageReference Include="X" Version="Y" /></ItemGroup> |
#:project |
參考其他專案 | <ItemGroup><ProjectReference Include="../lib/lib.csproj" /></ItemGroup> |
CLI 會解析這些 directives,建立對應的記憶體內 MSBuild Project,然後再進入建置流程。
為了降低「一次性小工具」的啟動成本,設計了多層快取與跳躍機制:
.cs
檔內容,且 MSBuild 結構未變(無新增 directives、套件),可直接呼叫 Roslyn 編譯器(csc
)跳過完整 MSBuild 評估 — 可透過 FileBasedProgramCanSkipMSBuild=false
停用。--no-cache
強制重建;亦支援環境變數調整快取策略。%TEMP%/dotnet-file-based/<hash>
(Windows 類似路徑;其他平台在使用者 cache/temp 目錄下)。<hash>
以 entry 檔案的完整路徑 + 關鍵設定(如 TFM、RuntimeIdentifier)計算,確保不同來源不互相覆蓋。dotnet clean-file-based-app-artifacts
立即清理DOTNET_CLI_DISABLE_FILE_BASED_APP_ARTIFACTS_AUTOMATIC_CLEANUP=true
關閉自動清理單檔模式支援與傳統專案一致的大部分指令並套用特化預設:
dotnet run file.cs
:主流程;內部等同「隱式還原 + 快取判斷 + 可能增量編譯 + 執行」。dotnet build file.cs
:產生(或更新)產物但不執行。dotnet publish file.cs
:支援包含 Native AOT 預設啟用(若環境條件成立)。dotnet pack file.cs
:會生成一個暫時性專案以封裝成 NuGet(使用者較少用,但為一致性保留)。dotnet clean file.cs
:清除該單檔對應 Hash 目錄。dotnet restore file.cs
:解析 directives 中的 package dependencies;若無套件則可能直接 no-op。特殊差異:
dotnet run hello.cs
└── 解析參數:檢測是 file-based 模式
└── 建構 FileBasedAppContext(路徑、Hash、快取目錄)
├── 讀取/解析 directives -> 建立 In-Memory Project
├── 計算變更指紋 (hash of source + directives + packages)
├── 快取命中?
│ ├── 是 -> 直接執行輸出
│ └── 否 -> (可能)走快路徑 csc 編譯或完整 MSBuild
└── 更新快取記錄 & 啟動執行
.csproj
,保留 directives 內容遷移至專案檔 <PropertyGroup>
/ <ItemGroup>
。