关于 package-management
使用 dotnet CLI 管理 .NET 项目 NuGet 包的技能,涵盖包操作、中央包管理、还原故障排查及跨项目版本一致性。
主要功能
- 01通过 dotnet 命令管理包
- 02配置中央包管理
- 03列出过时及传递依赖包
- 04还原包并清理缓存
- 05排查版本冲突
- 06使用锁定文件实现可复现构建
适用场景
- 01添加或移除 NuGet 依赖
- 02管理解决方案中各项目的版本
- 03诊断包还原失败
- 04调查依赖冲突
安装
复制下面的命令,在终端中运行。
$
npx skills add https:/ / github.com/ aaronontheweb/ dotnet-skills --skill package-management安装后在 Claude Code 中输入/package-management确认已加载。
详细介绍
NuGet 包管理
何时使用此技能
在以下情况下使用此技能:
- 添加、移除或更新 NuGet 包
- 为解决方案设置中央包管理(CPM)
- 管理多个项目中的包版本
- 排查包冲突或还原问题
黄金法则:绝不直接编辑 XML
**始终使用 dotnet CLI 命令管理包。**绝不要手动编辑 .csproj 或 Directory.Packages.props 文件。
# DO: Use CLI commands
dotnet add package Newtonsoft.Json
dotnet remove package Newtonsoft.Json
dotnet list package --outdated
# DON'T: Edit XML directly
# <PackageReference Include="Newtonsoft.Json" Version="13.0.3" />
原因:
- CLI 会验证包是否存在,并解析正确的版本
- 正确处理传递依赖
- 如有锁定文件,会更新这些文件
- 避免拼写错误和格式错误的 XML
- 可与 CPM 正常配合使用
中央包管理(CPM)
CPM 会将所有包版本集中在一个文件中,从而消除项目之间的版本冲突。
启用 CPM
在解决方案根目录中创建 Directory.Packages.props:
<Project>
<PropertyGroup>
<ManagePackageVersionsCentrally>true</ManagePackageVersionsCentrally>
</PropertyGroup>
<ItemGroup>
<PackageVersion Include="Newtonsoft.Json" Version="13.0.3" />
<PackageVersion Include="Serilog" Version="4.0.0" />
<PackageVersion Include="xunit" Version="2.9.2" />
</ItemGroup>
</Project>
使用 CPM 的项目文件
项目引用包时不带版本号:
<Project Sdk="Microsoft.NET.Sdk">
<ItemGroup>
<PackageReference Include="Newtonsoft.Json" />
<PackageReference Include="Serilog" />
</ItemGroup>
</Project>
使用 CPM 添加包
# Adds to Directory.Packages.props AND project file
dotnet add package Serilog.Sinks.Console
# Result in Directory.Packages.props:
# <PackageVersion Include="Serilog.Sinks.Console" Version="6.0.0" />
# Result in project file:
# <PackageReference Include="Serilog.Sinks.Console" />
共享版本变量
使用共享版本变量对相关包进行分组:
<Project>
<PropertyGroup>
<ManagePackageVersionsCentrally>true</ManagePackageVersionsCentrally>
</PropertyGroup>
<PropertyGroup Label="SharedVersions">
<AkkaVersion>1.5.59</AkkaVersion>
<AkkaHostingVersion>1.5.59</AkkaHostingVersion>
<AspireVersion>9.0.0</AspireVersion>
<OpenTelemetryVersion>1.11.0</OpenTelemetryVersion>
<XunitVersion>2.9.2</XunitVersion>
</PropertyGroup>
<ItemGroup Label="Akka.NET">
<PackageVersion Include="Akka" Version="$(AkkaVersion)" />
<PackageVersion Include="Akka.Cluster" Version="$(AkkaVersion)" />
<PackageVersion Include="Akka.Cluster.Sharding" Version="$(AkkaVersion)" />
<PackageVersion Include="Akka.Cluster.Tools" Version="$(AkkaVersion)" />
<PackageVersion Include="Akka.Persistence" Version="$(AkkaVersion)" />
<PackageVersion Include="Akka.Streams" Version="$(AkkaVersion)" />
<PackageVersion Include="Akka.Hosting" Version="$(AkkaHostingVersion)" />
<PackageVersion Include="Akka.Cluster.Hosting" Version="$(AkkaHostingVersion)" />
</ItemGroup>
<ItemGroup Label="Aspire">
<PackageVersion Include="Aspire.Hosting" Version="$(AspireVersion)" />
<PackageVersion Include="Aspire.Hosting.AppHost" Version="$(AspireVersion)" />
<PackageVersion Include="Aspire.Hosting.PostgreSQL" Version="$(AspireVersion)" />
<PackageVersion Include="Aspire.Hosting.Testing" Version="$(AspireVersion)" />
</ItemGroup>
<ItemGroup Label="OpenTelemetry">
<PackageVersion Include="OpenTelemetry.Exporter.OpenTelemetryProtocol" Version="$(OpenTelemetryVersion)" />
<PackageVersion Include="OpenTelemetry.Extensions.Hosting" Version="$(OpenTelemetryVersion)" />
<PackageVersion Include="OpenTelemetry.Instrumentation.AspNetCore" Version="$(OpenTelemetryVersion)" />
<PackageVersion Include="OpenTelemetry.Instrumentation.Http" Version="$(OpenTelemetryVersion)" />
</ItemGroup>
<ItemGroup Label="Testing">
<PackageVersion Include="xunit" Version="$(XunitVersion)" />
<PackageVersion Include="xunit.runner.visualstudio" Version="$(XunitVersion)" />
<PackageVersion Include="FluentAssertions" Version="6.12.0" />
<PackageVersion Include="Verify.Xunit" Version="26.0.0" />
</ItemGroup>
</Project>
优点:
- 更改一个变量即可更新所有 Akka 包
- 通过带标签的 ItemGroup 清晰地组织内容
- 防止相关包之间出现版本不匹配
不适合使用 CPM 的情况
中央包管理并非总是合适的选择:
旧版项目
将现有的大型解决方案迁移到 CPM 可能会引入问题:
- 现有的版本冲突会一下子全部暴露出来
- 某些包可能有意使用不同的版本
- 迁移需要同时修改许多文件
建议:对于旧版项目,请逐步迁移;如果按项目管理版本的方式运行良好,也可以继续使用。
版本范围
CPM 要求使用精确版本,不支持版本范围:
<PackageVersion Include="Newtonsoft.Json" Version="[13.0,14.0)" />
<PackageVersion Include="Newtonsoft.Json" Version="13.0.3" />
如果需要使用版本范围(这种情况很少见,但某些库场景有此要求),CPM 就不适用。
较旧的 .NET 版本
CPM 要求:
- .NET SDK 6.0.300+ 或更高版本
- NuGet 6.2+ 或更高版本
- Visual Studio 2022 17.2+ 或更高版本
如果目标是较旧版本的 SDK,或者团队成员使用较旧的工具,CPM 可能会导致构建失败。
多仓库解决方案
如果解决方案跨多个独立构建的仓库,CPM 的单个 Directory.Packages.props 文件将无法提供帮助——每个仓库都需要自己的文件。
CLI 命令参考
添加包
# Add latest stable version
dotnet add package Serilog
# Add specific version
dotnet add package Serilog --version 4.0.0
# Add prerelease
dotnet add package Serilog --prerelease
# Add to specific project
dotnet add src/MyApp/MyApp.csproj package Serilog
移除包
# Remove from current project
dotnet remove package Serilog
# Remove from specific project
dotnet remove src/MyApp/MyApp.csproj package Serilog
列出包
# List all packages in solution
dotnet list package
# Show outdated packages
dotnet list package --outdated
# Include transitive dependencies
dotnet list package --include-transitive
# Show vulnerable packages
dotnet list package --vulnerable
# Show deprecated packages
dotnet list package --deprecated
更新包
# With CPM: Edit the version in Directory.Packages.props
# Then restore to apply
dotnet restore
# Without CPM: Remove and add with new version
dotnet remove package Serilog
dotnet add package Serilog --version 4.1.0
# Or use dotnet-outdated tool (recommended)
dotnet tool install --global dotnet-outdated-tool
dotnet outdated --upgrade
还原和清理
# Restore packages
dotnet restore
# Clear local cache (troubleshooting)
dotnet nuget locals all --clear
# Force restore (ignore cache)
dotnet restore --force
包源
列出源
dotnet nuget list source
添加私有源
# Add authenticated feed
dotnet nuget add source https://pkgs.dev.azure.com/myorg/_packaging/myfeed/nuget/v3/index.json \
--name MyFeed \
--username az \
--password $PAT \
--store-password-in-clear-text
NuGet.config
如需配置解决方案专用的源,请创建 NuGet.config:
<?xml version="1.0" encoding="utf-8"?>
<configuration>
<packageSources>
<clear />
<add key="nuget.org" value="https://api.nuget.org/v3/index.json" />
<add key="MyPrivateFeed" value="https://pkgs.dev.azure.com/myorg/_packaging/myfeed/nuget/v3/index.json" />
</packageSources>
<packageSourceCredentials>
<MyPrivateFeed>
<add key="Username" value="az" />
<add key="ClearTextPassword" value="%NUGET_PAT%" />
</MyPrivateFeed>
</packageSourceCredentials>
</configuration>
常见模式
仅用于开发的包
<PackageVersion Include="Microsoft.SourceLink.GitHub" Version="8.0.0" />
<PackageReference Include="Microsoft.SourceLink.GitHub" PrivateAssets="All" />
条件包
<ItemGroup Condition="'$(Configuration)' == 'Debug'">
<PackageReference Include="JetBrains.Annotations" />
</ItemGroup>
<ItemGroup Condition="'$(TargetFramework)' == 'net8.0'">
<PackageReference Include="System.Text.Json" />
</ItemGroup>
版本覆盖(应急方案)
必须在某个项目中覆盖 CPM 时(很少见):
<PackageReference Include="Newtonsoft.Json" VersionOverride="12.0.3" />
警告:Slopwatch 会将此情况检测为潜在的 slop(参见 dotnet/slopwatch 技能)。
故障排查
版本冲突
# See full dependency tree
dotnet list package --include-transitive
# Find what's pulling in a specific package
dotnet list package --include-transitive | grep -i "PackageName"
还原失败
# Clear all caches
dotnet nuget locals all --clear
# Restore with detailed logging
dotnet restore --verbosity detailed
# Check for locked packages
cat packages.lock.json
锁定文件
如需实现可重现构建,请使用包锁定文件:
<PropertyGroup>
<RestorePackagesWithLockFile>true</RestorePackagesWithLockFile>
</PropertyGroup>
然后提交 packages.lock.json 文件。
反模式
不要:直接编辑 XML
<PackageReference Include="Typo.Package" Version="1.0.0" />
不要:在 CPM 中内联版本号
<PackageReference Include="Serilog" Version="4.0.0" />
<PackageReference Include="Serilog" />
不要:混用版本管理方式
<PackageReference Include="Serilog" />
<PackageReference Include="Newtonsoft.Json" Version="13.0.3" />
不要:忘记共享变量
<PackageVersion Include="Akka" Version="1.5.59" />
<PackageVersion Include="Akka.Cluster" Version="1.5.58" />
<PackageVersion Include="Akka" Version="$(AkkaVersion)" />
<PackageVersion Include="Akka.Cluster" Version="$(AkkaVersion)" />
快速参考
| 任务 | 命令 |
|---|---|
| 添加包 | dotnet add package <name> |
| 添加指定版本 | dotnet add package <name> --version <ver> |
| 移除包 | dotnet remove package <name> |
| 列出包 | dotnet list package |
| 查看过时包 | dotnet list package --outdated |
| 查看易受攻击的包 | dotnet list package --vulnerable |
| 还原 | dotnet restore |
| 清除缓存 | dotnet nuget locals all --clear |
Resources
- Central Package Management: https://learn.microsoft.com/en-us/nuget/consume-packages/central-package-management
- dotnet CLI Reference: https://learn.microsoft.com/en-us/dotnet/core/tools/
- NuGet.config Reference: https://learn.microsoft.com/en-us/nuget/reference/nuget-config-file
评论
支持 Markdown