.NET 10 中的新增功能系列文章4——.NET SDK中的新增功能

引言

随着 .NET 10 的发布,.NET SDK 迎来了一系列令人振奋的新功能和增强特性。这些改进不仅提升了开发者的工作效率,还优化了应用程序的性能和部署体验。本文将详细介绍 .NET 10 SDK 中的新增功能,包括工具改进、基于文件的应用增强、包引用修剪等,帮助开发者充分利用这些新特性来构建更高效的应用程序。

正文

.NET 工具改进

特定于平台的 .NET 工具

.NET 10 引入了对多平台 .NET 工具的增强支持,开发者现在可以在单个包中发布支持多个 RuntimeIdentifier (RID) 的工具。这意味着工具作者可以捆绑所有受支持平台的二进制文件,而 .NET CLI 会在安装或运行时自动选择正确的二进制文件。这一改进显著简化了跨平台工具的创作和分发流程。

这些改进的工具支持多种包装变体:

  • 依赖于框架,平台无关(经典模式,任何安装了 .NET 10 的地方都可以运行)
  • 框架依赖,平台特定(更小,针对每个平台进行优化)
  • 自包含,平台特定(包含运行时,无需安装 .NET)
  • 裁剪版,平台特定(更小,裁剪未使用的代码)
  • 平台特定的 AOT 编译(最大性能和最小部署)

这些新工具的工作方式与常规的已发布应用程序非常相似,因此任何可用于应用程序的发布选项(如自包含、剪裁或 AOT 编译)也同样适用于这些工具。

单次工具执行

.NET 10 引入了 dotnet tool exec 命令,允许开发者执行 .NET 工具而无需全局或本地安装该工具。这对于 CI/CD 或临时使用场景尤其有用。

bash 复制代码
dotnet tool exec --source ./artifacts/package/ toolsay "Hello, World!"

执行此命令会下载并运行指定的工具包。如果工具本地不存在,系统会提示用户确认下载。除非指定显式版本(如 toolsay@0.1.0),否则将使用工具包的最新版本。

新的 dnx 工具执行脚本

dnx 脚本提供了一种简化的方式来执行工具,它将所有参数转发到 dotnet CLI 进行处理:

bash 复制代码
dnx toolsay "Hello, World!"

dnx 命令的实际实现是在 CLI 本身的 dotnet 中,这允许其行为随时间推移而演变。

通过 --cli-schema 实现的 CLI 自省

所有 CLI 命令上都新增了 --cli-schema 选项。使用时,它会输出调用的命令或子命令的 CLI 命令树的 JSON 表示形式,这对于工具作者、shell 集成和高级脚本非常有用。

bash 复制代码
dotnet clean --cli-schema

输出示例:

json 复制代码
{
  "name": "clean",
  "version": "10.0.100-dev",
  "description": ".NET Clean Command",
  "arguments": {
    "PROJECT | SOLUTION": {
      "description": "The project or solution file to operate on...",
      "arity": { "minimum": 0, "maximum": null }
    }
  },
  "options": {
    "--artifacts-path": {
      "description": "The artifacts path...",
      "helpName": "ARTIFACTS_DIR"
    }
  },
  "subcommands": {}
}

基于文件的应用程序功能增强

具备发布支持和本地 AOT 的增强

基于文件的应用现在支持通过 dotnet publish app.cs 命令发布到本机可执行文件,默认情况下,所有基于文件的应用都以本机 AOT 为目标。如果需要使用与本机 AOT 不兼容的包或功能,可以使用 #:property PublishAot=false 指令禁用此功能。

基于文件的应用还包括以下增强功能:

  • 项目引用:支持通过 #:project 指令引用项目
  • 运行时路径访问:应用程序文件和目录的路径可在运行时通过 System.AppContext.GetData 访问
  • 增强了 shebang 支持:通过改进的 shebang 处理(包括支持无扩展名文件),直接执行 shell 脚本

项目引用示例:

csharp 复制代码
#:project ../ClassLib/ClassLib.csproj

var greeter = new ClassLib.Greeter();
var greeting = greeter.Greet(args.Length > 0 ? args[0] : "World");
Console.WriteLine(greeting);

增强的 shebang 支持示例:

csharp 复制代码
#!/usr/bin/env dotnet

Console.WriteLine("Hello shebang!");

修剪由框架提供的包引用

从 .NET 10 开始,NuGet 审核功能现在可以修剪项目不使用的框架提供的包引用。默认情况下,所有 net 目标框架(如 net8.0net10.0)以及 .NET Standard 2.0 及更高版本的目标框架都启用此功能。

此更改有助于:

  • 减少生成过程中还原和分析的包数量
  • 缩短生成时间
  • 减少磁盘空间使用量
  • 减少来自 NuGet 审计以及其他依赖项扫描机制的误报情况

虽然此功能默认为列出的 TPM 启用,但可以通过在项目文件中将 RestoreEnablePackagePruning 属性设置为 false 来禁用此功能。

更一致的命令顺序

.NET 10 引入了常见命令的新别名,使它们更易于记住和键入:

新名词优先形式 别名
dotnet package add dotnet add package
dotnet package list dotnet list package
dotnet package remove dotnet remove package
dotnet reference add dotnet add reference
dotnet reference list dotnet list reference
dotnet reference remove dotnet remove reference

新的名词优先表单符合一般 CLI 标准,使 dotnet CLI 与其他工具更加一致。虽然动词优先表单继续工作,但建议使用名词优先表单以提高脚本和文档中的可读性和一致性。

CLI 命令默认为交互式终端中的交互模式

在交互式终端中,现在默认启用 --interactive 标志用于 CLI 命令。此更改允许命令动态检索凭据或执行其他交互行为,而无需显式设置标志。对于非交互方案,可以通过指定 --interactive false 来禁用交互性。

原生 shell Tab 补全脚本

dotnet CLI 现在支持使用 dotnet completions generate [SHELL] 命令为常用 shell 生成原生 Tab 补全脚本。支持的 shell 包括:

  • bash
  • fish
  • nushell
  • powershell
  • zsh

例如,在 PowerShell 中,可以通过将以下内容添加到 $PROFILE 中来启用补全功能:

控制台应用可以原生创建容器映像

控制台应用现在可以通过 dotnet publish /t:PublishContainer 创建容器映像,而无需在项目文件中包含 <EnableSdkContainerSupport> 属性。这使控制台应用与 ASP.NET Core 和 Worker SDK 应用的行为保持一致。

使用新的 <ContainerImageFormat> 属性可以显式地将容器映像的格式设置为 Docker 或 OCI。此属性替代默认行为,具体取决于基本映像格式以及容器是否为多体系结构。

支持 dotnet test 中的 Microsoft 测试平台

从 .NET 10 开始,dotnet test 原生支持 Microsoft.Testing.Platform。要启用此功能,可以将以下配置添加到 dotnet.config 文件:

ini 复制代码
[dotnet.test.runner]
name = "Microsoft.Testing.Platform"

系列文章

.NET 10 中的新增功能系列文章1------运行时中的新增功能

.NET 10 中的新增功能系列文章2------ASP.NET Core 中的新增功能

.NET 10 中的新增功能系列文章3------.NET MAUI 中的新增功能