--- name: dotnet-centralized-packages description: Guide for Centralized Package Management (CPM) using Directory.Packages.props in .NET projects type: domain enforcement: suggest priority: high --- # Centralized 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 1. [What is CPM](#what-is-cpm) 2. [Project Configuration](#project-configuration) 3. [Adding Packages](#adding-packages) 4. [Updating Packages](#updating-packages) 5. [Package Structure](#package-structure) 6. [Troubleshooting](#troubleshooting) 7. [Best Practices](#best-practices) 8. [Quick Reference](#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): ```xml ``` **CPM approach** (used in this project): ```xml ``` --- ## Project Configuration ### Directory.Packages.props Located at solution root (`/Directory.Packages.props`): ```xml true true ``` ### 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: ```xml net10.0 disable disable true ``` --- ## Adding Packages ### Step-by-Step Process **Step 1**: Add version to `Directory.Packages.props` ```xml ``` **Step 2**: Add reference to `.csproj` (WITHOUT version) ```xml ``` ### Examples from This Project **Adding MSTest (already in project):** ```xml ``` **Adding Razor Runtime Compilation (already in project):** ```xml ``` ### Common Mistakes **WRONG - Adding Version to .csproj:** ```xml ``` **Error message:** ``` error NU1008: Version information is not allowed for central package versions. ``` **CORRECT - No Version in .csproj:** ```xml ``` ### Using dotnet add package When using `dotnet add package`, you MUST add the version separately: ```bash # Step 1: Add to Directory.Packages.props manually # Edit Directory.Packages.props and add: # # Step 2: Add reference to project dotnet add src/ClaudeStack.Web/ClaudeStack.Web.csproj package Newtonsoft.Json # OR manually add to .csproj: # ``` **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`: ```xml ``` 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 ```bash # 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: ```xml ``` Use explicit versions for reproducibility. --- ## Package Structure ### Organizing with ItemGroup Labels This project uses labeled ItemGroups for organization: ```xml ``` 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 ```bash # 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 ```xml ``` ### Issue: "Package not found" after adding to .csproj **Cause**: Package version not defined in Directory.Packages.props. **Solution**: Add to Directory.Packages.props: ```xml ``` ### 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:** 1. **Preferred**: Standardize on one version across all projects 2. **Workaround** (not recommended): Disable CPM for specific packages using `VersionOverride` ```xml ``` ### Issue: Transitive dependency conflicts **Symptom**: Build errors about incompatible transitive dependencies. **Solution**: Enable `CentralPackageTransitivePinningEnabled`: ```xml true ``` 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: ```bash # 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: 1. Add `` to Directory.Packages.props 2. Then add `` to .csproj ### 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]` - `10.0.0-rc.2.25502.107`: Major=10, Minor=0, Patch=0, Prerelease=rc.2.25502.107 ### 4. Group Packages Logically Use labeled ItemGroups: - Core Packages - Testing Packages - Analysis Packages - Development Packages ### 5. Review Transitive Dependencies ```bash dotnet list package --include-transitive ``` Understand what indirect dependencies your project uses. ### 6. Update Carefully When updating packages: 1. Test in development first 2. Update one package at a time (for critical packages) 3. 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 ```xml ``` ### Updating a Package ```xml ``` ### Common Commands ```bash # 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 ```xml true true ``` ### 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 - [Microsoft CPM Documentation](https://learn.microsoft.com/en-us/nuget/consume-packages/central-package-management) - [NuGet Package Version Reference](https://learn.microsoft.com/en-us/nuget/concepts/package-versioning) - [Directory.Build.props Documentation](https://learn.microsoft.com/en-us/visualstudio/msbuild/customize-by-directory) --- ## 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.