중앙 패키지 관리(CPM)

종속성 관리는 NuGet의 핵심 기능입니다. 단일 프로젝트에 대한 종속성을 쉽게 관리할 수 있습니다. 다중 프로젝트 솔루션에 대한 종속성 관리는 해당 관리가 크기와 복잡성의 스케일 인을 위해 시작된다는 점에서 어려운 작업이 될 수 있습니다. 다양한 프로젝트에 대한 일반적인 종속성을 관리하는 경우, NuGet의 중앙 패키지 관리 기능(CPM)을 활용하여 단일 위치의 용이성을 통해 이 모든 작업을 수행할 수 있습니다.

과거에는 NuGet 패키지의 종속성을 다음의 두 위치 중 한 곳에서 관리했습니다.

  • packages.config - 예전의 프로젝트 형식에서는 프로젝트가 참조하는 패키지 목록을 유지하기 위해 XML 파일을 사용했습니다.
  • <PackageReference /> - MSBuild 프로젝트에 사용되는 XML 요소는 NuGet 패키지 종속성을 정의합니다.

NuGet 6.2를 사용하면서부터는 Directory.Packages.props 파일과 MSBuild 속성을 추가해 프로젝트의 종속성을 중앙에서 관리할 수 있습니다.

이 기능은 다음 버전부터 모든 NuGet 통합 도구에서 사용할 수 있습니다.

이전 도구는 중앙 패키지 관리 구성 및 기능을 무시합니다. 이 기능을 최대한으로 사용하려면 모든 빌드 환경에서 호환되는 최신 도구 버전을 사용해야 합니다.

중앙 패키지 관리는 호환되는 도구를 사용하는 동안에는 레거시 CSPROJ를 포함해 모든 <PackageReference> 기반 MSBuild 프로젝트에 적용됩니다.

중앙 패키지 관리 사용

중앙 패키지 관리를 시작하려면 리포지토리의 루트에 Directory.Packages.props 파일을 만들고 MSBuild 속성 ManagePackageVersionsCentrally을(를) true(으)로 설정해야 합니다.

그 안에서 패키지 ID와 버전을 정의하는 <PackageVersion /> 요소를 사용해 프로젝트에 필요한 각각의 패키지 버전을 정의할 수 있습니다.

<Project>
  <PropertyGroup>
    <ManagePackageVersionsCentrally>true</ManagePackageVersionsCentrally>
  </PropertyGroup>
  <ItemGroup>
    <PackageVersion Include="Newtonsoft.Json" Version="13.0.1" />
  </ItemGroup>
</Project>

그런 다음 각 프로젝트에 대해 해당 항목에서 <PackageReference />을 정의하지만, 버전이 해당 <PackageVersion /> 항목에서 획득되므로 Version 속성을 생략합니다.

<Project Sdk="Microsoft.NET.Sdk">
  <PropertyGroup>
    <TargetFramework>net6.0</TargetFramework>
  </PropertyGroup>
  <ItemGroup>
    <PackageReference Include="Newtonsoft.Json" />
  </ItemGroup>
</Project>

이제 중앙 패키지 관리를 사용할 수 있으며 버전들을 중앙의 한 지점에서 관리합니다.

중앙 패키지 관리 규칙

Directory.Packages.props 파일에는 리포지토리의 디렉터리와 컨텍스트 상에서 해당 파일이 어디에 있어야 하는지에 대한 다양한 규칙이 있습니다. 간결성을 위해 대상 프로젝트에 대해서는 하나의 Directory.Packages.props 파일 만이 평가됩니다.

이는 리포지토리에 Directory.Packages.props 파일이 여러 개 있어도 프로젝트 디렉터리에서 가장 가까운 파일만 해당 프로젝트와 관련해 평가된다는 의미입니다. 이렇게 하면 리포지토리의 다양한 수준에 대해 추가로 컨트롤할 수 있습니다.

다음 예제에서는 다음의 리포지토리 구조체를 사용해 봅니다.

Repository
 |-- Directory.Packages.props
 |-- Solution1
     |-- Directory.Packages.props
     |-- Project1
 |-- Solution2
     |-- Project2
  • Project1은 Repository\Solution1\ 디렉터리의 Directory.Packages.props 파일을 평가할 수 있는데, 그럴 경우 다음 파일은 수동으로 가져와야 합니다.
    <Project>
      <Import Project="$([MSBuild]::GetPathOfFileAbove(Directory.Packages.props, $(MSBuildThisFileDirectory)..))" />
      <ItemGroup>
        <PackageVersion Update="Newtonsoft.Json" Version="12.0.1" />
      </ItemGroup>
    </Project>
    
  • Project2는 Repository\ 디렉터리의 Directory.Packages.props 파일을 평가합니다.

참고: MSBuild는 각각의 Directory.Packages.props을(를) 자동으로 가져오지 않고 프로젝트에 가장 가까운 첫 번째 항목만 가져옵니다. 복수의 Directory.Packages.props이(가) 있는 경우, 루트 Directory.Packages.props이(가) 가져오지 않으면 부모 항목을 수동으로 가져와야 합니다.

시작하기

리포지토리를 완전히 온보딩하려면 다음 단계에 따라 수행하는 것이 좋습니다.

  1. 중앙에서 정의한 패키지 버전을 선언하는 Directory.Packages.props 리포지토리의 루트에 새 파일을 만들고 MSBuild 속성 ManagePackageVersionsCentrally을(를) true(으)로 설정합니다.
  2. <PackageVersion /> 항목을 Directory.Packages.props에 선언합니다.
  3. 프로젝트 파일에 <PackageReference /> 항목을 Version 특성 없이 선언합니다.

중앙 패키지 관리의 모양은 샘플 리포지토리를 참조하세요.

전이적 고정

전이적 고정이라는 기능을 옵트인하여 명시적인 최상위 수준의 <PackageReference /> 없이도 전이적 패키지 버전을 자동으로 재정의할 수 있습니다. 이렇게 하면 필요에 따라 사용자를 대신해서 전의적 종속성을 함축적으로 최상위 종속성으로 승격합니다.

프로젝트나 Directory.Packages.props 또는 Directory.Build.props 가져오기 파일에서 MSBuild 속성인 CentralPackageTransitivePinningEnabledtrue로 설정해 이 기능을 사용하도록 설정할 수 있습니다.

<PropertyGroup>
  <CentralPackageTransitivePinningEnabled>true</CentralPackageTransitivePinningEnabled>
</PropertyGroup>

패키지 버전 재정의

<PackageReference /> 항목의 VersionOverride 속성을 사용하면 개별 패키지 버전을 재정의할 수 있습니다. 이렇게 하면 정의한 모든 <PackageVersion />을 중앙에서 재정의합니다.

<Project>
  <ItemGroup>
    <PackageVersion Include="PackageA" Version="1.0.0" />
    <PackageVersion Include="PackageB" Version="2.0.0" />
  </ItemGroup>
</Project>
<Project Sdk="Microsoft.NET.Sdk">
  <PropertyGroup>
    <TargetFramework>net6.0</TargetFramework>
  </PropertyGroup>
  <ItemGroup>
    <PackageReference Include="PackageA" VersionOverride="3.0.0" />
  </ItemGroup>
</Project>

프로젝트나 Directory.Packages.props 또는 Directory.Build.props 가져오기 파일에서 MSBuild 속성인 CentralPackageVersionOverrideEnabledfalse로 설정하여 이 기능을 사용하지 않도록 설정할 수 있습니다.

<PropertyGroup>
  <CentralPackageVersionOverrideEnabled>false</CentralPackageVersionOverrideEnabled>
</PropertyGroup>

이 기능을 사용하지 않을 때는 어떤 <PackageReference /> 항목에 대해 VersionOverride를 지정하더라도 해당 기능이 비활성화되었다는 의미로서 복원 시간에 오류가 발생합니다.

중앙 패키지 관리 사용 해제

특정 프로젝트에 대해 중앙 패키지 관리를 사용하지 않으려면 MSBuild 속성 ManagePackageVersionsCentrally을(를) false(으)로 설정하십시오.

<PropertyGroup>
  <ManagePackageVersionsCentrally>false</ManagePackageVersionsCentrally>
</PropertyGroup>

전역 패키지 참조

참고 항목

이 기능은 Visual Studio 2022 17.4 이상, .NET SDK 7.0.100.preview7 이상 및 NuGet 6.4 이상에서만 사용할 수 있습니다.

전역 패키지 참조는 리포지토리의 모든 프로젝트에서 패키지를 사용하도록 지정하는 데 사용됩니다. 여기에는 버전 관리를 수행하는 패키지, 빌드 확장 또는 모든 프로젝트에 필요한 다른 패키지가 포함됩니다. 전역 패키지 참조는 다음 메타데이터를 사용하여 PackageReference 항목 그룹에 추가됩니다.

  • IncludeAssets="Runtime;Build;Native;contentFiles;Analyzers"
    이렇게 하면 패키지가 개발 종속성으로만 사용되고 컴파일 시간 어셈블리 참조를 방지할 수 있습니다.
  • PrivateAssets="All"
    이렇게 하면 다운스트림 종속성에 의해 전역 패키지 참조가 선택되지 않습니다.

GlobalPackageReference 리포지토리의 Directory.Packages.props 모든 프로젝트에서 사용할 항목을 배치해야 합니다.

<Project>
  <ItemGroup>
    <GlobalPackageReference Include="Nerdbank.GitVersioning" Version="3.5.109" />
  </ItemGroup>
</Project>

다양한 패키지 소스를 사용할 때 표시되는 경고

중앙 패키지 관리를 사용하면 구성에 정의된 패키지 소스가 둘 이상일 때 NU1507 경고가 표시됩니다. 이 경고를 해결하려면 패키지 소스 매핑을 통해 패키지 소스를 매핑하거나 단일 패키지 소스를 지정합니다.

There are 3 package sources defined in your configuration. When using central package management, please map your package sources with package source mapping (https://aka.ms/nuget-package-source-mapping) or specify a single package source.

참고 항목

중앙 패키지 관리는 현재 개발 중입니다. 사용해 보고 NuGet/Home에 피드백을 제공해 주셔서 감사합니다.