mcpField
P
package-management

package-management

github.com/aaronontheweb开发1.2k594 次安装今天更新
代码仓库

关于 package-management

使用 dotnet CLI 管理 .NET 项目 NuGet 包的技能,涵盖包操作、中央包管理、还原故障排查及跨项目版本一致性。

主要功能

  1. 01通过 dotnet 命令管理包
  2. 02配置中央包管理
  3. 03列出过时及传递依赖包
  4. 04还原包并清理缓存
  5. 05排查版本冲突
  6. 06使用锁定文件实现可复现构建

适用场景

  1. 01添加或移除 NuGet 依赖
  2. 02管理解决方案中各项目的版本
  3. 03诊断包还原失败
  4. 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

评论

支持 Markdown