Claude-skill-registry dotnet-centralized-packages
Guide for Centralized Package Management (CPM) using Directory.Packages.props in .NET projects
git clone https://github.com/majiayu000/claude-skill-registry
T=$(mktemp -d) && git clone --depth=1 https://github.com/majiayu000/claude-skill-registry "$T" && mkdir -p ~/.claude/skills && cp -r "$T/skills/data/dotnet-centralized-packages" ~/.claude/skills/majiayu000-claude-skill-registry-dotnet-centralized-packages && rm -rf "$T"
skills/data/dotnet-centralized-packages/SKILL.mdCentralized Package Management (CPM)
This skill provides guidance for using Central Package Management (CPM) with
Directory.Packages.props in this .NET 10 project. CPM manages all NuGet package versions in one central location.
Table of Contents
- What is CPM
- Project Configuration
- Adding Packages
- Updating Packages
- Package Structure
- Troubleshooting
- Best Practices
- Quick Reference
What is CPM
Overview
Centralized Package Management (CPM) is a NuGet feature that centralizes package version management in a single
Directory.Packages.props file at the solution root.
Benefits:
- Single source of truth for package versions
- No version conflicts across projects
- Easier updates - change version in one place
- Better dependency management
- Simpler project files
How It Works
Traditional approach (NOT used in this project):
<!-- Each .csproj specifies versions --> <PackageReference Include="MSTest" Version="4.0.0-preview.25465.3" />
CPM approach (used in this project):
<!-- Directory.Packages.props defines versions --> <PackageVersion Include="MSTest" Version="4.0.0-preview.25465.3" /> <!-- .csproj references WITHOUT version --> <PackageReference Include="MSTest" />
Project Configuration
Directory.Packages.props
Located at solution root (
/Directory.Packages.props):
<Project> <PropertyGroup> <ManagePackageVersionsCentrally>true</ManagePackageVersionsCentrally> <CentralPackageTransitivePinningEnabled>true</CentralPackageTransitivePinningEnabled> </PropertyGroup> <ItemGroup Label="Core Packages"> <PackageVersion Include="Microsoft.AspNetCore.Mvc.Razor.RuntimeCompilation" Version="10.0.0-rc.2.25502.107" /> <PackageVersion Include="Microsoft.AspNetCore.OpenApi" Version="10.0.0-rc.2.25502.107" /> </ItemGroup> <ItemGroup Label="Testing Packages"> <PackageVersion Include="MSTest" Version="4.0.0-preview.25465.3" /> <PackageVersion Include="Microsoft.Playwright.MSTest.v4" Version="1.55.0-beta-4" /> </ItemGroup> </Project>
Key Properties
ManagePackageVersionsCentrally: Enables CPM. All versions must be in Directory.Packages.props.
CentralPackageTransitivePinningEnabled: Pins transitive dependency versions to prevent unexpected updates.
Directory.Build.props Integration
CPM works alongside
Directory.Build.props which defines shared MSBuild properties:
<Project> <PropertyGroup> <TargetFramework>net10.0</TargetFramework> <Nullable>disable</Nullable> <ImplicitUsings>disable</ImplicitUsings> <TreatWarningsAsErrors>true</TreatWarningsAsErrors> </PropertyGroup> </Project>
Adding Packages
Step-by-Step Process
Step 1: Add version to
Directory.Packages.props
<ItemGroup Label="Your Category"> <PackageVersion Include="Newtonsoft.Json" Version="13.0.3" /> </ItemGroup>
Step 2: Add reference to
.csproj (WITHOUT version)
<ItemGroup> <PackageReference Include="Newtonsoft.Json" /> </ItemGroup>
Examples from This Project
Adding MSTest (already in project):
<!-- Directory.Packages.props --> <PackageVersion Include="MSTest" Version="4.0.0-preview.25465.3" /> <!-- tests/ClaudeStack.Web.Tests/ClaudeStack.Web.Tests.csproj --> <PackageReference Include="MSTest" />
Adding Razor Runtime Compilation (already in project):
<!-- Directory.Packages.props --> <PackageVersion Include="Microsoft.AspNetCore.Mvc.Razor.RuntimeCompilation" Version="10.0.0-rc.2.25502.107" /> <!-- src/ClaudeStack.Web/ClaudeStack.Web.csproj --> <PackageReference Include="Microsoft.AspNetCore.Mvc.Razor.RuntimeCompilation" />
Common Mistakes
WRONG - Adding Version to .csproj:
<!-- This will FAIL with CPM enabled --> <PackageReference Include="MSTest" Version="4.0.0-preview.25465.3" />
Error message:
error NU1008: Version information is not allowed for central package versions.
CORRECT - No Version in .csproj:
<PackageReference Include="MSTest" />
Using dotnet add package
When using
dotnet add package, you MUST add the version separately:
# Step 1: Add to Directory.Packages.props manually # Edit Directory.Packages.props and add: # <PackageVersion Include="Newtonsoft.Json" Version="13.0.3" /> # Step 2: Add reference to project dotnet add src/ClaudeStack.Web/ClaudeStack.Web.csproj package Newtonsoft.Json # OR manually add to .csproj: # <PackageReference Include="Newtonsoft.Json" />
Note:
dotnet add package may not automatically update Directory.Packages.props. Manual editing is often required.
Updating Packages
Update Single Package
Edit
Directory.Packages.props:
<!-- Before --> <PackageVersion Include="MSTest" Version="4.0.0-preview.25465.3" /> <!-- After --> <PackageVersion Include="MSTest" Version="4.0.0" />
This updates the package across all projects that reference it.
Update Multiple Packages
Edit versions in Directory.Packages.props. All projects will use the new versions automatically.
Update All Packages to Latest
# List outdated packages dotnet list package --outdated # Update packages in Directory.Packages.props based on output # (Manual process - edit Directory.Packages.props) # Restore to apply changes dotnet restore
Version Ranges (Not Recommended)
CPM supports version ranges, but not recommended for this project:
<!-- Avoid this pattern --> <PackageVersion Include="MSTest" Version="[4.0.0,5.0.0)" />
Use explicit versions for reproducibility.
Package Structure
Organizing with ItemGroup Labels
This project uses labeled ItemGroups for organization:
<ItemGroup Label="Core Packages"> <!-- ASP.NET Core packages --> </ItemGroup> <ItemGroup Label="Testing Packages"> <!-- MSTest, Playwright, etc. --> </ItemGroup> <ItemGroup Label="Analysis Packages"> <!-- Code analysis tools --> </ItemGroup>
Labels are optional but improve readability.
Current Packages in Project
Core Packages:
- Microsoft.AspNetCore.Mvc.Razor.RuntimeCompilation: 10.0.0-rc.2.25502.107
- Microsoft.AspNetCore.OpenApi: 10.0.0-rc.2.25502.107
Testing Packages:
- MSTest: 4.0.0-preview.25465.3
- Microsoft.Playwright.MSTest.v4: 1.55.0-beta-4
Viewing All Packages
# List all packages in solution dotnet list package # Include transitive dependencies dotnet list package --include-transitive
Troubleshooting
Issue: "Version information is not allowed"
Full Error:
error NU1008: Version information is not allowed for central package versions.
Cause: PackageReference in .csproj includes Version attribute when CPM is enabled.
Solution: Remove Version from .csproj
<!-- WRONG --> <PackageReference Include="MSTest" Version="4.0.0-preview.25465.3" /> <!-- CORRECT --> <PackageReference Include="MSTest" />
Issue: "Package not found" after adding to .csproj
Cause: Package version not defined in Directory.Packages.props.
Solution: Add to Directory.Packages.props:
<PackageVersion Include="PackageName" Version="x.y.z" />
Issue: Different projects use different versions
Symptom: Project A uses v1.0, Project B uses v2.0 of same package.
Cause: With CPM, all projects must use the same version. This is by design.
Solutions:
- Preferred: Standardize on one version across all projects
- Workaround (not recommended): Disable CPM for specific packages using
VersionOverride
<!-- In .csproj, override version (not recommended) --> <PackageReference Include="MSTest" VersionOverride="3.0.0" />
Issue: Transitive dependency conflicts
Symptom: Build errors about incompatible transitive dependencies.
Solution: Enable
CentralPackageTransitivePinningEnabled:
<PropertyGroup> <CentralPackageTransitivePinningEnabled>true</CentralPackageTransitivePinningEnabled> </PropertyGroup>
Already enabled in this project.
Issue: dotnet add package doesn't work
Symptom:
dotnet add package adds reference but version is missing from Directory.Packages.props.
Solution: Manually add version to Directory.Packages.props (this is expected behavior).
Issue: Restore fails after adding package
Solution: Ensure package exists on NuGet.org or configured feeds:
# Clear NuGet cache dotnet nuget locals all --clear # Restore dotnet restore
Best Practices
1. Always Edit Directory.Packages.props First
When adding a new package:
- Add
to Directory.Packages.props<PackageVersion> - Then add
to .csproj<PackageReference>
2. Keep Versions Consistent
Avoid mixing preview and stable versions unnecessarily. This project uses preview packages because it targets .NET 10 RC 2.
3. Use Semantic Versioning
Understand version numbers:
Major.Minor.Patch[-Prerelease]
: Major=10, Minor=0, Patch=0, Prerelease=rc.2.25502.10710.0.0-rc.2.25502.107
4. Group Packages Logically
Use labeled ItemGroups:
- Core Packages
- Testing Packages
- Analysis Packages
- Development Packages
5. Review Transitive Dependencies
dotnet list package --include-transitive
Understand what indirect dependencies your project uses.
6. Update Carefully
When updating packages:
- Test in development first
- Update one package at a time (for critical packages)
- Run full test suite after updates
7. Document Breaking Changes
When updating major versions, document breaking changes in commit messages or project documentation.
8. Avoid VersionOverride
Only use
VersionOverride as a last resort. It defeats the purpose of CPM.
Quick Reference
File Locations
/Directory.Packages.props - Package versions (central) /Directory.Build.props - Shared build properties /**/*.csproj - Package references (no versions)
Adding a Package
<!-- Step 1: Directory.Packages.props --> <PackageVersion Include="PackageName" Version="x.y.z" /> <!-- Step 2: ProjectFile.csproj --> <PackageReference Include="PackageName" />
Updating a Package
<!-- Directory.Packages.props - change version --> <PackageVersion Include="PackageName" Version="x.y.z" /> <!-- All projects automatically use new version -->
Common Commands
# List packages dotnet list package # List outdated packages dotnet list package --outdated # List transitive dependencies dotnet list package --include-transitive # Restore packages dotnet restore # Clear cache and restore dotnet nuget locals all --clear && dotnet restore
Directory.Packages.props Template
<Project> <PropertyGroup> <ManagePackageVersionsCentrally>true</ManagePackageVersionsCentrally> <CentralPackageTransitivePinningEnabled>true</CentralPackageTransitivePinningEnabled> </PropertyGroup> <ItemGroup Label="Category Name"> <PackageVersion Include="PackageName" Version="x.y.z" /> </ItemGroup> </Project>
Error Reference
| Error | Cause | Solution |
|---|---|---|
| NU1008 | Version in .csproj | Remove Version attribute |
| Package not found | Missing from Directory.Packages.props | Add PackageVersion |
| Version conflict | Different versions needed | Use single version or VersionOverride |
Related Skills
- mstest-testing-platform: MSTest package configuration and usage
- playwright-dotnet: Playwright package setup and testing
- dotnet-cli-essentials: Package commands (list, add, restore)
Additional Resources
Version Information
This project uses:
- .NET SDK: 10.0.100-rc.2.25502.107
- NuGet CPM: Supported in .NET 6.0+ SDK
- MSBuild: 17.0+
CPM is a stable NuGet feature as of .NET 6.0 SDK.