package-management
Compare original and translation side by side
🇺🇸
Original
English🇨🇳
Translation
ChineseNuGet Package Management
NuGet包管理
When to Use This Skill
何时使用此技能
Use this skill when:
- Adding, removing, or updating NuGet packages
- Setting up Central Package Management (CPM) for a solution
- Managing package versions across multiple projects
- Troubleshooting package conflicts or restore issues
在以下场景使用此技能:
- 添加、移除或更新NuGet包时
- 为解决方案设置Central Package Management (CPM)时
- 跨多个项目管理包版本时
- 排查包冲突或还原问题时
Golden Rule: Never Edit XML Directly
黄金准则:切勿直接编辑XML文件
Always use CLI commands to manage packages. Never manually edit or files.
dotnet.csprojDirectory.Packages.propsbash
undefined**请始终使用 CLI命令管理包。**切勿手动编辑或文件。
dotnet.csprojDirectory.Packages.propsbash
undefinedDO: Use CLI commands
DO: Use CLI commands
dotnet add package Newtonsoft.Json
dotnet remove package Newtonsoft.Json
dotnet list package --outdated
dotnet add package Newtonsoft.Json
dotnet remove package Newtonsoft.Json
dotnet list package --outdated
DON'T: Edit XML directly
DON'T: Edit XML directly
<PackageReference Include="Newtonsoft.Json" Version="13.0.3" />
<PackageReference Include="Newtonsoft.Json" Version="13.0.3" />
**Why:**
- CLI validates package exists and resolves correct version
- Handles transitive dependencies correctly
- Updates lock files if present
- Avoids typos and malformed XML
- Works correctly with CPM
---
**原因:**
- CLI会验证包是否存在并解析正确版本
- 正确处理传递依赖
- 若存在锁定文件则会更新
- 避免拼写错误和格式错误的XML
- 与CPM兼容
---Central Package Management (CPM)
Central Package Management (CPM) 集中包管理
CPM centralizes all package versions in one file, eliminating version conflicts across projects.
CPM将所有包版本集中在一个文件中,消除跨项目的版本冲突。
Enable CPM
启用CPM
Create in solution root:
Directory.Packages.propsxml
<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>在解决方案根目录创建文件:
Directory.Packages.propsxml
<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>Project Files with CPM
使用CPM的项目文件
Projects reference packages without versions:
xml
<!-- src/MyApp/MyApp.csproj -->
<Project Sdk="Microsoft.NET.Sdk">
<ItemGroup>
<PackageReference Include="Newtonsoft.Json" />
<PackageReference Include="Serilog" />
</ItemGroup>
</Project>项目引用包时无需指定版本:
xml
<!-- src/MyApp/MyApp.csproj -->
<Project Sdk="Microsoft.NET.Sdk">
<ItemGroup>
<PackageReference Include="Newtonsoft.Json" />
<PackageReference Include="Serilog" />
</ItemGroup>
</Project>Adding Packages with CPM
使用CPM添加包
bash
undefinedbash
undefinedAdds to Directory.Packages.props AND project file
Adds to Directory.Packages.props AND project file
dotnet add package Serilog.Sinks.Console
dotnet add package Serilog.Sinks.Console
Result in Directory.Packages.props:
Result in Directory.Packages.props:
<PackageVersion Include="Serilog.Sinks.Console" Version="6.0.0" />
<PackageVersion Include="Serilog.Sinks.Console" Version="6.0.0" />
Result in project file:
Result in project file:
<PackageReference Include="Serilog.Sinks.Console" />
<PackageReference Include="Serilog.Sinks.Console" />
---
---Shared Version Variables
共享版本变量
Group related packages with shared version variables:
xml
<Project>
<PropertyGroup>
<ManagePackageVersionsCentrally>true</ManagePackageVersionsCentrally>
</PropertyGroup>
<!-- Shared version variables -->
<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>
<!-- Akka.NET packages - all use same version -->
<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>
<!-- Aspire packages -->
<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>
<!-- OpenTelemetry packages -->
<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>
<!-- Testing -->
<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>Benefits:
- Update all Akka packages by changing one variable
- Clear organization with labeled ItemGroups
- Prevents version mismatches in related packages
使用共享版本变量对相关包进行分组:
xml
<Project>
<PropertyGroup>
<ManagePackageVersionsCentrally>true</ManagePackageVersionsCentrally>
</PropertyGroup>
<!-- Shared version variables -->
<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>
<!-- Akka.NET packages - all use same version -->
<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>
<!-- Aspire packages -->
<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>
<!-- OpenTelemetry packages -->
<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>
<!-- Testing -->
<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实现清晰的组织
- 避免相关包出现版本不匹配的问题
When NOT to Use CPM
何时不使用CPM
Central Package Management isn't always the right choice:
集中包管理并非在所有场景下都适用:
Legacy Projects
遗留项目
Migrating an existing large solution to CPM can introduce issues:
- Existing version conflicts become visible all at once
- Some packages may have intentional version differences
- Migration requires touching many files simultaneously
Recommendation: For legacy projects, migrate incrementally or stick with per-project versioning if it's working.
将现有大型解决方案迁移到CPM可能会引发问题:
- 现有的版本冲突会一次性全部显现
- 某些包可能有意使用不同版本
- 迁移需要同时修改大量文件
建议:对于遗留项目,可逐步迁移;若当前的按项目版本管理方式运行正常,可继续使用。
Version Ranges
版本范围
CPM requires exact versions - it doesn't support version ranges:
xml
<!-- NOT supported with CPM -->
<PackageVersion Include="Newtonsoft.Json" Version="[13.0,14.0)" />
<!-- Must use exact version -->
<PackageVersion Include="Newtonsoft.Json" Version="13.0.3" />If you need version ranges (rare, but some library scenarios require it), CPM won't work.
CPM要求使用精确版本——不支持版本范围:
xml
<!-- NOT supported with CPM -->
<PackageVersion Include="Newtonsoft.Json" Version="[13.0,14.0)" />
<!-- Must use exact version -->
<PackageVersion Include="Newtonsoft.Json" Version="13.0.3" />如果您需要使用版本范围(这种情况很少见,但某些库场景下需要),则CPM不适用。
Older .NET Versions
旧版.NET版本
CPM requires:
- .NET SDK 6.0.300+ or later
- NuGet 6.2+ or later
- Visual Studio 2022 17.2+ or later
If you're targeting older SDK versions or have team members on older tooling, CPM may cause build failures.
CPM需要满足以下条件:
- **.NET SDK 6.0.300+**或更高版本
- **NuGet 6.2+**或更高版本
- **Visual Studio 2022 17.2+**或更高版本
如果您的项目目标是旧版SDK,或者团队成员使用旧版工具,CPM可能会导致构建失败。
Multi-Repo Solutions
多仓库解决方案
If your solution spans multiple repositories that are built independently, CPM's single won't help - each repo needs its own.
Directory.Packages.props如果您的解决方案跨越多个独立构建的仓库,CPM的单个文件无法发挥作用——每个仓库需要自己的配置文件。
Directory.Packages.propsCLI Command Reference
CLI命令参考
Adding Packages
添加包
bash
undefinedbash
undefinedAdd latest stable version
Add latest stable version
dotnet add package Serilog
dotnet add package Serilog
Add specific version
Add specific version
dotnet add package Serilog --version 4.0.0
dotnet add package Serilog --version 4.0.0
Add prerelease
Add prerelease
dotnet add package Serilog --prerelease
dotnet add package Serilog --prerelease
Add to specific project
Add to specific project
dotnet add src/MyApp/MyApp.csproj package Serilog
undefineddotnet add src/MyApp/MyApp.csproj package Serilog
undefinedRemoving Packages
移除包
bash
undefinedbash
undefinedRemove from current project
Remove from current project
dotnet remove package Serilog
dotnet remove package Serilog
Remove from specific project
Remove from specific project
dotnet remove src/MyApp/MyApp.csproj package Serilog
undefineddotnet remove src/MyApp/MyApp.csproj package Serilog
undefinedListing Packages
列出包
bash
undefinedbash
undefinedList all packages in solution
List all packages in solution
dotnet list package
dotnet list package
Show outdated packages
Show outdated packages
dotnet list package --outdated
dotnet list package --outdated
Include transitive dependencies
Include transitive dependencies
dotnet list package --include-transitive
dotnet list package --include-transitive
Show vulnerable packages
Show vulnerable packages
dotnet list package --vulnerable
dotnet list package --vulnerable
Show deprecated packages
Show deprecated packages
dotnet list package --deprecated
undefineddotnet list package --deprecated
undefinedUpdating Packages
更新包
bash
undefinedbash
undefinedWith CPM: Edit the version in Directory.Packages.props
With CPM: Edit the version in Directory.Packages.props
Then restore to apply
Then restore to apply
dotnet restore
dotnet restore
Without CPM: Remove and add with new version
Without CPM: Remove and add with new version
dotnet remove package Serilog
dotnet add package Serilog --version 4.1.0
dotnet remove package Serilog
dotnet add package Serilog --version 4.1.0
Or use dotnet-outdated tool (recommended)
Or use dotnet-outdated tool (recommended)
dotnet tool install --global dotnet-outdated-tool
dotnet outdated --upgrade
undefineddotnet tool install --global dotnet-outdated-tool
dotnet outdated --upgrade
undefinedRestore and Clean
还原与清理
bash
undefinedbash
undefinedRestore packages
Restore packages
dotnet restore
dotnet restore
Clear local cache (troubleshooting)
Clear local cache (troubleshooting)
dotnet nuget locals all --clear
dotnet nuget locals all --clear
Force restore (ignore cache)
Force restore (ignore cache)
dotnet restore --force
---dotnet restore --force
---Package Sources
包源
List Sources
列出源
bash
dotnet nuget list sourcebash
dotnet nuget list sourceAdd Private Feed
添加私有源
bash
undefinedbash
undefinedAdd authenticated feed
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
--name MyFeed
--username az
--password $PAT
--store-password-in-clear-text
undefineddotnet 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
--name MyFeed
--username az
--password $PAT
--store-password-in-clear-text
undefinedNuGet.config
NuGet.config
For solution-specific sources, create :
NuGet.configxml
<?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>针对特定解决方案的源,创建文件:
NuGet.configxml
<?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>Common Patterns
常见模式
Development-Only Packages
仅开发环境包
xml
<!-- Directory.Packages.props -->
<PackageVersion Include="Microsoft.SourceLink.GitHub" Version="8.0.0" />
<!-- Project file - mark as development dependency -->
<PackageReference Include="Microsoft.SourceLink.GitHub" PrivateAssets="All" />xml
<!-- Directory.Packages.props -->
<PackageVersion Include="Microsoft.SourceLink.GitHub" Version="8.0.0" />
<!-- Project file - mark as development dependency -->
<PackageReference Include="Microsoft.SourceLink.GitHub" PrivateAssets="All" />Conditional Packages
条件包
xml
<!-- Only include in Debug builds -->
<ItemGroup Condition="'$(Configuration)' == 'Debug'">
<PackageReference Include="JetBrains.Annotations" />
</ItemGroup>
<!-- Platform-specific -->
<ItemGroup Condition="'$(TargetFramework)' == 'net8.0'">
<PackageReference Include="System.Text.Json" />
</ItemGroup>xml
<!-- Only include in Debug builds -->
<ItemGroup Condition="'$(Configuration)' == 'Debug'">
<PackageReference Include="JetBrains.Annotations" />
</ItemGroup>
<!-- Platform-specific -->
<ItemGroup Condition="'$(TargetFramework)' == 'net8.0'">
<PackageReference Include="System.Text.Json" />
</ItemGroup>Version Override (Escape Hatch)
版本覆盖(应急方案)
When you must override CPM for one project (rare):
xml
<!-- Project file - use sparingly! -->
<PackageReference Include="Newtonsoft.Json" VersionOverride="12.0.3" />Warning: This is detected by Slopwatch (see skill) as potential slop.
dotnet/slopwatch当您必须为单个项目覆盖CPM配置时(这种情况很少见):
xml
<!-- Project file - use sparingly! -->
<PackageReference Include="Newtonsoft.Json" VersionOverride="12.0.3" />警告:Slopwatch(请查看技能)会将此检测为潜在的不良实践。
dotnet/slopwatchTroubleshooting
排查问题
Version Conflicts
版本冲突
bash
undefinedbash
undefinedSee full dependency tree
See full dependency tree
dotnet list package --include-transitive
dotnet list package --include-transitive
Find what's pulling in a specific package
Find what's pulling in a specific package
dotnet list package --include-transitive | grep -i "PackageName"
undefineddotnet list package --include-transitive | grep -i "PackageName"
undefinedRestore Failures
还原失败
bash
undefinedbash
undefinedClear all caches
Clear all caches
dotnet nuget locals all --clear
dotnet nuget locals all --clear
Restore with detailed logging
Restore with detailed logging
dotnet restore --verbosity detailed
dotnet restore --verbosity detailed
Check for locked packages
Check for locked packages
cat packages.lock.json
undefinedcat packages.lock.json
undefinedLock Files
锁定文件
For reproducible builds, use package lock files:
xml
<!-- Directory.Build.props -->
<PropertyGroup>
<RestorePackagesWithLockFile>true</RestorePackagesWithLockFile>
</PropertyGroup>Then commit files.
packages.lock.json为了实现可复现的构建,请使用包锁定文件:
xml
<!-- Directory.Build.props -->
<PropertyGroup>
<RestorePackagesWithLockFile>true</RestorePackagesWithLockFile>
</PropertyGroup>然后提交文件。
packages.lock.jsonAnti-Patterns
反模式
Don't: Edit XML Directly
切勿:直接编辑XML文件
xml
<!-- BAD: Manual XML editing -->
<PackageReference Include="Typo.Package" Version="1.0.0" />
<!-- Package might not exist! CLI would catch this. -->xml
<!-- BAD: Manual XML editing -->
<PackageReference Include="Typo.Package" Version="1.0.0" />
<!-- Package might not exist! CLI would catch this. -->Don't: Inline Versions with CPM
切勿:在CPM中使用内联版本
xml
<!-- BAD: Bypasses CPM -->
<PackageReference Include="Serilog" Version="4.0.0" />
<!-- GOOD: Version comes from Directory.Packages.props -->
<PackageReference Include="Serilog" />xml
<!-- BAD: Bypasses CPM -->
<PackageReference Include="Serilog" Version="4.0.0" />
<!-- GOOD: Version comes from Directory.Packages.props -->
<PackageReference Include="Serilog" />Don't: Mix Version Management
切勿:混合版本管理方式
xml
<!-- BAD: Some versions in CPM, some inline -->
<PackageReference Include="Serilog" /> <!-- From CPM -->
<PackageReference Include="Newtonsoft.Json" Version="13.0.3" /> <!-- Inline -->xml
<!-- BAD: Some versions in CPM, some inline -->
<PackageReference Include="Serilog" /> <!-- From CPM -->
<PackageReference Include="Newtonsoft.Json" Version="13.0.3" /> <!-- Inline -->Don't: Forget Shared Variables
切勿:忘记使用共享变量
xml
<!-- BAD: Related packages with different versions -->
<PackageVersion Include="Akka" Version="1.5.59" />
<PackageVersion Include="Akka.Cluster" Version="1.5.58" /> <!-- Mismatch! -->
<!-- GOOD: Use shared variable -->
<PackageVersion Include="Akka" Version="$(AkkaVersion)" />
<PackageVersion Include="Akka.Cluster" Version="$(AkkaVersion)" />xml
<!-- BAD: Related packages with different versions -->
<PackageVersion Include="Akka" Version="1.5.59" />
<PackageVersion Include="Akka.Cluster" Version="1.5.58" /> <!-- Mismatch! -->
<!-- GOOD: Use shared variable -->
<PackageVersion Include="Akka" Version="$(AkkaVersion)" />
<PackageVersion Include="Akka.Cluster" Version="$(AkkaVersion)" />Quick Reference
快速参考
| Task | Command |
|---|---|
| Add package | |
| Add specific version | |
| Remove package | |
| List packages | |
| Show outdated | |
| Show vulnerable | |
| Restore | |
| Clear cache | |
| 任务 | 命令 |
|---|---|
| 添加包 | |
| 添加指定版本 | |
| 移除包 | |
| 列出包 | |
| 显示过时包 | |
| 显示存在漏洞的包 | |
| 还原包 | |
| 清理缓存 | |
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
- Central Package Management:https://learn.microsoft.com/en-us/nuget/consume-packages/central-package-management
- dotnet CLI参考:https://learn.microsoft.com/en-us/dotnet/core/tools/
- NuGet.config参考:https://learn.microsoft.com/en-us/nuget/reference/nuget-config-file