본문으로 건너뛰기
cccskills
무료GitHub에 공개

package-management

Manage NuGet packages using Central Package Management (CPM) and dotnet CLI commands. Never edit XML directly - use dotnet add/remove/list commands. Use shared version variables for related packages.

한국어 요약은 준비 중입니다. 원문 설명을 표시하고 있습니다.

설치 방법 보기

포함된 파일(1)

  • SKILL.md11.9 KB

SKILL.md(원문)

설치하기 전에 에이전트에게 전달되는 지시 내용을 확인할 수 있습니다.

NuGet Package Management

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

Golden Rule: Never Edit XML Directly

Always use dotnet CLI commands to manage packages. Never manually edit .csproj or Directory.Packages.props files.

# 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" />

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

Central Package Management (CPM)

CPM centralizes all package versions in one file, eliminating version conflicts across projects.

Enable CPM

Create Directory.Packages.props in solution root:

<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

Projects reference packages without versions:

<!-- src/MyApp/MyApp.csproj -->
<Project Sdk="Microsoft.NET.Sdk">
  <ItemGroup>
    <PackageReference Include="Newtonsoft.Json" />
    <PackageReference Include="Serilog" />
  </ItemGroup>
</Project>

Adding Packages with 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" />

Shared Version Variables

Group related packages with shared version variables:

<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

When NOT to Use 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.

Version Ranges

CPM requires exact versions - it doesn't support version ranges:

<!-- 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.

Older .NET Versions

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.

Multi-Repo Solutions

If your solution spans multiple repositories that are built independently, CPM's single Directory.Packages.props won't help - each repo needs its own.


CLI Command Reference

Adding Packages

# 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

Removing Packages

# Remove from current project
dotnet remove package Serilog

# Remove from specific project
dotnet remove src/MyApp/MyApp.csproj package Serilog

Listing Packages

# 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

Updating Packages

# 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 and Clean

# Restore packages
dotnet restore

# Clear local cache (troubleshooting)
dotnet nuget locals all --clear

# Force restore (ignore cache)
dotnet restore --force

Package Sources

List Sources

dotnet nuget list source

Add Private 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

NuGet.config

For solution-specific sources, create 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>

Common Patterns

Development-Only Packages

<!-- 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

<!-- 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):

<!-- Project file - use sparingly! -->
<PackageReference Include="Newtonsoft.Json" VersionOverride="12.0.3" />

Warning: This is detected by Slopwatch (see dotnet/slopwatch skill) as potential slop.


Troubleshooting

Version Conflicts

# 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"

Restore Failures

# Clear all caches
dotnet nuget locals all --clear

# Restore with detailed logging
dotnet restore --verbosity detailed

# Check for locked packages
cat packages.lock.json

Lock Files

For reproducible builds, use package lock files:

<!-- Directory.Build.props -->
<PropertyGroup>
  <RestorePackagesWithLockFile>true</RestorePackagesWithLockFile>
</PropertyGroup>

Then commit packages.lock.json files.


Anti-Patterns

Don't: Edit XML Directly

<!-- 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

<!-- 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

<!-- 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

<!-- 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

TaskCommand
Add packagedotnet add package <name>
Add specific versiondotnet add package <name> --version <ver>
Remove packagedotnet remove package <name>
List packagesdotnet list package
Show outdateddotnet list package --outdated
Show vulnerabledotnet list package --vulnerable
Restoredotnet restore
Clear cachedotnet nuget locals all --clear

Resources

리뷰

아직 리뷰가 없습니다. 사용해 본 소감을 남겨 주세요.

댓글

로그인 없이 쓸 수 있습니다. 사용 후기, 질문, 작동하지 않은 환경 등을 편하게 남겨 주세요.

아직 댓글이 없습니다. 첫 댓글을 남겨 보세요.

보내면 바로 공개됩니다. 이메일 주소나 전화번호 같은 개인 정보는 쓰지 마세요. URL은 2개까지입니다.

0 / 1,000자

이 양식은 reCAPTCHA로 보호되며 Google 개인정보처리방침 및 서비스 약관이 적용됩니다.

같은 저장소의 스킬

Patterns for building entity actors with Akka.Hosting - GenericChildPerEntityParent, message extractors, cluster sharding abstraction, akka-reminders, and ITimeProvider. Supports both local testing and clustered production modes.

한국어 요약은 준비 중입니다. 원문 설명을 표시하고 있습니다.

Aaronontheweb/dotnet-skills1.2천2026년 10월 12일 업데이트

Configure Akka.NET with .NET Aspire for local development and production deployments. Covers actor system setup, clustering, persistence, Akka.Management integration, and Aspire orchestration patterns.

한국어 요약은 준비 중입니다. 원문 설명을 표시하고 있습니다.

Aaronontheweb/dotnet-skills1.2천2026년 10월 12일 업데이트

Critical Akka.NET best practices including EventStream vs DistributedPubSub, supervision strategies, error handling, Props vs DependencyResolver, work distribution patterns, and cluster/local mode abstractions for testability.

한국어 요약은 준비 중입니다. 원문 설명을 표시하고 있습니다.

Aaronontheweb/dotnet-skills1.2천2026년 10월 12일 업데이트

Akka.Management for cluster bootstrapping, service discovery (Kubernetes, Azure, Config), health checks, and dynamic cluster formation without static seed nodes.

한국어 요약은 준비 중입니다. 원문 설명을 표시하고 있습니다.

Aaronontheweb/dotnet-skills1.2천2026년 10월 12일 업데이트

Write unit and integration tests for Akka.NET actors using modern Akka.Hosting.TestKit patterns. Covers dependency injection, TestProbes, persistence testing, and actor interaction verification. Includes guidance on when to use traditional TestKit.

한국어 요약은 준비 중입니다. 원문 설명을 표시하고 있습니다.

Aaronontheweb/dotnet-skills1.2천2026년 10월 12일 업데이트

Guidelines for making .NET libraries and applications trimming-safe and Native AOT compatible. Covers the trimming/AOT model, the MSBuild properties that enable analysis (IsTrimmable, IsAotCompatible, PublishTrimmed, PublishAot), the trimming attributes (RequiresUnreferencedCode, RequiresDynamicCode, DynamicallyAccessedMembers, UnconditionalSuppressMessage), IL2xxx/IL3xxx warning codes, and a pattern playbook: source generators and UnsafeAccessor, generated-interception diagnostic suppressors, intentional runtime scanning boundaries, trimming-safe islands and feature switches, migration analyzers, and temporary warning-approval baselines. Use when introducing trimming/AOT support, resolving IL2xxx/IL3xxx warnings, or making reflection-heavy code trimming-safe in C# / .NET codebases. For System.Text.Json AOT scenarios, see also the serialization skill.

한국어 요약은 준비 중입니다. 원문 설명을 표시하고 있습니다.

Aaronontheweb/dotnet-skills1.2천2026년 10월 12일 업데이트

Aaronontheweb의 스킬 모두 보기

이 스킬의 문제 신고