Community코딩 & 개발github.com

패키지 관리

중앙 패키지 관리(CPM)와 dotnet CLI 명령어를 사용하여 NuGet 패키지를 관리합니다. XML을 직접 편집하지 말고 항상 dotnet add/remove/list 명령어를 사용하세요. 관련 패키지에는 공유 버전 변수를 사용하세요.

패키지 관리란 무엇인가요?

이 스킬은 .NET 개발자가 NuGet 패키지를 효율적이고 안전하게 관리하는 방법을 제공합니다. 중앙 패키지 관리(CPM)를 설정하고 사용하는 방법, dotnet CLI 명령어를 사용하여 패키지를 추가/제거/업데이트하는 방법, 그리고 관련 패키지 그룹에 공유 버전 변수를 적용하여 버전 불일치를 방지하는 방법을 다룹니다. 또한, CPM이 적합하지 않은 레거시 프로젝트나 특정 시나리오(버전 범위, 오래된 .NET SDK 등)에 대한 대안도 제시합니다. 이 스킬은 Cursor, Codex, Claude Code 등 모든 주요 AI 에이전트 플랫폼에서 사용할 수 있으며, XML을 직접 수정하지 않고 CLI 명령어를 사용하도록 강제하여 오류를 줄이고 일관성을 유지하는 데 중점을 둡니다.

지원 대상~Claude Code~Codex CLI~Cursor
npx skills add https://github.com/Aaronontheweb/dotnet-skills/tree/main/skills/package-management

Installed? Explore more 코딩 & 개발 skills: steipete/bluebubbles, steipete/eightctl, steipete/blucli · View all 6 →

즐겨 사용하는 AI에게 물어보기

이 에이전트 스킬이 미리 로드된 새 채팅을 엽니다.

문서

NuGet 패키지 관리

이 스킬을 사용해야 하는 경우

다음과 같은 경우에 이 스킬을 사용하세요:

  • NuGet 패키지 추가, 제거 또는 업데이트
  • 솔루션에 대한 중앙 패키지 관리(CPM) 설정
  • 여러 프로젝트에서 패키지 버전 관리
  • 패키지 충돌 또는 복원 문제 해결

황금률: XML을 직접 편집하지 마세요

패키지 관리를 위해 항상 dotnet CLI 명령어를 사용하세요. .csproj 또는 Directory.Packages.props 파일을 수동으로 편집하지 마세요.

# 권장: CLI 명령어 사용
dotnet add package Newtonsoft.Json
dotnet remove package Newtonsoft.Json
dotnet list package --outdated

# 비권장: XML 직접 편집
# <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을 사용하는 프로젝트 파일

프로젝트는 버전 없이 패키지를 참조합니다:

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

CPM으로 패키지 추가하기

# Directory.Packages.props와 프로젝트 파일에 모두 추가됩니다.
dotnet add package Serilog.Sinks.Console

# Directory.Packages.props 결과:
# <PackageVersion Include="Serilog.Sinks.Console" Version="6.0.0" />

# 프로젝트 파일 결과:
# <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>

  <!-- Akka.NET 패키지 - 모두 동일한 버전 사용 -->
  <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 패키지 -->
  <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 패키지 -->
  <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은 정확한 버전이 필요합니다. 버전 범위를 지원하지 않습니다:

<!-- 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 명령어 참조

패키지 추가하기

# 최신 안정 버전 추가
dotnet add package Serilog

# 특정 버전 추가
dotnet add package Serilog --version 4.0.0

# 시험판 추가
dotnet add package Serilog --prerelease

# 특정 프로젝트에 추가
dotnet add src/MyApp/MyApp.csproj package Serilog

패키지 제거하기

# 현재 프로젝트에서 제거
dotnet remove package Serilog

# 특정 프로젝트에서 제거
dotnet remove src/MyApp/MyApp.csproj package Serilog

패키지 나열하기

# 솔루션의 모든 패키지 나열
dotnet list package

# 업데이트 가능한 패키지 표시
dotnet list package --outdated

# 전이 종속성 포함
dotnet list package --include-transitive

# 취약한 패키지 표시
dotnet list package --vulnerable

# 사용되지 않는 패키지 표시
dotnet list package --deprecated

패키지 업데이트하기

# CPM 사용 시: Directory.Packages.props에서 버전 편집
# 그런 다음 복원하여 적용
dotnet restore

# CPM 미사용 시: 새 버전으로 제거 및 추가
dotnet remove package Serilog
dotnet add package Serilog --version 4.1.0

# 또는 dotnet-outdated 도구 사용 (권장)
dotnet tool install --global dotnet-outdated-tool
dotnet outdated --upgrade

복원 및 정리

# 패키지 복원
dotnet restore

# 로컬 캐시 지우기 (문제 해결)
dotnet nuget locals all --clear

# 강제 복원 (캐시 무시)
dotnet restore --force

패키지 소스

소스 나열하기

dotnet nuget list source

비공개 피드 추가하기

# 인증된 피드 추가
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>

일반적인 패턴

개발 전용 패키지

<!-- Directory.Packages.props -->
<PackageVersion Include="Microsoft.SourceLink.GitHub" Version="8.0.0" />

<!-- 프로젝트 파일 - 개발 종속성으로 표시 -->
<PackageReference Include="Microsoft.SourceLink.GitHub" PrivateAssets="All" />

조건부 패키지

<!-- Debug 빌드에만 포함 -->
<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(dotnet/slopwatch 스킬 참조)에서 잠재적인 슬롭으로 감지됩니다.


문제 해결

버전 충돌

# 전체 종속성 트리 보기
dotnet list package --include-transitive

# 특정 패키지를 참조하는 항목 찾기
dotnet list package --include-transitive | grep -i "PackageName"

복원 실패

# 모든 캐시 지우기
dotnet nuget locals all --clear

# 상세 로깅과 함께 복원
dotnet restore --verbosity detailed

# 잠긴 패키지 확인
cat packages.lock.json

잠금 파일

재현 가능한 빌드를 위해 패키지 잠금 파일을 사용하세요:

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

그런 다음 packages.lock.json 파일을 커밋하세요.


안티 패턴

하지 말아야 할 것: XML 직접 편집

<!-- 나쁨: 수동 XML 편집 -->
<PackageReference Include="Typo.Package" Version="1.0.0" />
<!-- 패키지가 존재하지 않을 수 있습니다! CLI가 이를 감지합니다. -->

하지 말아야 할 것: CPM과 함께 인라인 버전 사용

<!-- 나쁨: CPM 우회 -->
<PackageReference Include="Serilog" Version="4.0.0" />

<!-- 좋음: 버전이 Directory.Packages.props에서 가져옴 -->
<PackageReference Include="Serilog" />

하지 말아야 할 것: 버전 관리 혼합

<!-- 나쁨: 일부 버전은 CPM, 일부는 인라인 -->
<PackageReference Include="Serilog" />  <!-- CPM에서 -->
<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

리소스

Individual skills in this repo

This repo contains 20 individual skills — each has its own dedicated page.

akka-hosting-actor-patterns

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.

akka-net-aspire-configuration

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.

akka-net-best-practices

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.

akka-net-management

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

akka-net-testing-patterns

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.

api-design

Design stable, compatible public APIs using extend-only design principles. Manage API compatibility, wire compatibility, and versioning for NuGet packages and distributed systems.

aspire-configuration

Configure Aspire AppHost to emit explicit app config via environment variables; keep app code free of Aspire clients and service discovery.

aspire-integration-testing

Write integration tests using .NET Aspire

aspire-service-defaults

Create a shared ServiceDefaults project for Aspire applications. Centralizes OpenTelemetry, health checks, resilience, and service discovery configuration across all services.

crap-analysis

Analyze code coverage and CRAP (Change Risk Anti-Patterns) scores to identify high-risk code. Use OpenCover format with ReportGenerator for Risk Hotspots showing cyclomatic complexity and untested code paths.

csharp-concurrency-patterns

Choosing the right concurrency abstraction in .NET - from async/await for I/O to Channels for producer/consumer to Akka.NET for stateful entity management. Avoid locks and manual synchronization unless absolutely necessary.

database-performance

Database access patterns for performance. Separate read/write models, avoid N+1 queries, use AsNoTracking, apply row limits, and never do application-side joins. Works with EF Core and Dapper.

dependency-injection-patterns

Organize DI registrations using IServiceCollection extension methods. Group related services into composable Add* methods for clean Program.cs and reusable configuration in tests.

dotnet-devcert-trust

Diagnose and fix .NET HTTPS dev certificate trust issues on Linux. Covers the full certificate lifecycle from generation to system CA bundle inclusion, with distro-specific guidance for Ubuntu, Fedora, Arch, and WSL2.

dotnet-local-tools

Managing local .NET tools with dotnet-tools.json for consistent tooling across development environments and CI/CD pipelines.

dotnet-project-structure

Modern .NET project structure including .slnx solution format, Directory.Build.props, central package management, SourceLink, version management with RELEASE_NOTES.md, and SDK pinning with global.json.

dotnet-slopwatch

Use Slopwatch to detect LLM reward hacking in .NET code changes. Run after every code modification to catch disabled tests, suppressed warnings, empty catch blocks, and other shortcuts that mask real problems.

efcore-patterns

Entity Framework Core best practices including NoTracking by default, query splitting for navigation collections, migration management, dedicated migration services, and common pitfalls to avoid.

ilspy-decompile

Understand implementation details of .NET code by decompiling assemblies. Use when you want to see how a .NET API works internally, inspect NuGet package source, view framework implementation, or understand compiled .NET binaries.

mailpit-integration

Test email sending locally using Mailpit with .NET Aspire. Captures all outgoing emails without sending them. View rendered HTML, inspect headers, and verify delivery in integration tests.

관련 스킬