종속성 관리는 NuGet의 핵심 기능입니다. 단일 프로젝트에 대한 종속성을 관리하는 것은 간단하지만 솔루션의 프로젝트 수가 증가함에 따라 점점 더 복잡해집니다.
다양한 프로젝트에 대한 일반적인 종속성을 관리하는 경우 NuGet의 CPM(중앙 패키지 관리) 기능을 활용하여 단일 중앙 위치에서 이 모든 작업을 수행할 수 있습니다.
중앙 패키지 관리는 모든 <PackageReference>
기반 MSBuild 프로젝트( 레거시 CSPROJ 포함)에 적용됩니다.
중앙 패키지 관리를 활성화하기
중앙 패키지 관리를 시작하려면 리포지토리의 루트에 파일을 만들고 Directory.Packages.props
MSBuild 속성을 ManagePackageVersionsCentrally
true
.로 설정합니다.
수동으로 만들거나 .NET CLI를 사용할 수 있습니다.
dotnet new packagesprops
내부 Directory.Packages.props
에서 <PackageVersion />
요소를 정의하여 프로젝트에서 사용하는 패키지 ID 및 버전을 지정합니다.
<Project>
<PropertyGroup>
<ManagePackageVersionsCentrally>true</ManagePackageVersionsCentrally>
</PropertyGroup>
<ItemGroup>
<PackageVersion Include="PackageA" Version="1.0.0" />
<PackageVersion Include="PackageB" Version="2.0.0" />
</ItemGroup>
</Project>
각 프로젝트 파일에서 Version
특성을 사용하지 않고 <PackageReference />
요소를 정의합니다.
버전은 에 있는 해당 <PackageVersion />
항목 Directory.Packages.props
에서 확인됩니다.
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>net6.0</TargetFramework>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="PackageA" />
</ItemGroup>
</Project>
이제 중앙 패키지 관리를 사용하고 중앙 위치에서 버전을 관리합니다.
중앙 패키지 관리 규칙
파일에는 Directory.Packages.props
리포지토리 내의 위치 및 컨텍스트에 대한 특정 규칙이 있습니다.
기본적으로 지정된 프로젝트에 대해 하나의 Directory.Packages.props
파일만 평가됩니다.
리포지토리에 여러 Directory.Packages.props
파일이 있는 경우 지정된 프로젝트의 디렉터리에 가장 가까운 파일이 평가됩니다.
이렇게 하면 리포지토리의 다양한 수준에서 추가로 제어할 수 있습니다.
다음 리포지토리 디렉터리 구조를 고려합니다.
📂 (root)
├─📄 Directory.Packages.props
|
├─📂Solution1
| ├─ 📄Directory.Packages.props
| |
| └─ 📂 Project1
| └─📄Project1.csproj
|
└─ 📂 Solution2
└─ 📂 Project2
└─ 📄 Project2.csproj
Project1.csproj
는 Repository\Solution1\
디렉터리의 Directory.Packages.props
파일을 사용합니다.
부모의 Directory.Packages.props
설정을 포함하려면 수동으로 가져와야 합니다.
<Project>
<Import Project="$([MSBuild]::GetPathOfFileAbove(Directory.Packages.props, $(MSBuildThisFileDirectory)..))" />
<ItemGroup>
<PackageVersion Update="Newtonsoft.Json" Version="12.0.1" />
</ItemGroup>
</Project>
Project2.csproj
는 루트 디렉터리의 Directory.Packages.props
파일을 평가합니다.
메모
MSBuild는 프로젝트 디렉터리 또는 부모 디렉터리에서 찾은 첫 번째 Directory.Packages.props
파일만 자동으로 가져옵니다.
이러한 파일이 여러 대 있는 경우 필요에 따라 부모 파일을 수동으로 가져와야 합니다.
시작하기
리포지토리를 완전히 온보딩하려면 다음 단계를 수행합니다.
- 중앙에서 정의된 패키지 버전을 선언하고 MSBuild 속성
Directory.Packages.props
ManagePackageVersionsCentrally
설정하는true
리포지토리의 루트에 새 파일을 만듭니다. -
<PackageVersion />
항목을 귀하의Directory.Packages.props
에서 선언하십시오. - 프로젝트 파일에서
<PackageReference />
특성 없이Version
항목을 선언합니다.
중앙 패키지 관리의 모양에 대한 예제는 샘플 리포지토리를 참조하세요.
다른 대상 프레임워크에 다른 버전 사용
NuGet 패키지가 진화함에 따라 패키지 소유자는 이전 대상 프레임워크에 대한 지원을 삭제할 수 있습니다. 이로 인해 이전 프레임워크를 대상으로 하지만 최신 대상 프레임워크에 대한 최신 버전의 패키지를 참조하려는 라이브러리 개발자에게 문제가 발생할 수 있습니다.
예를 들어 프로젝트가 .NET Standard 2.0, .NET 8.0 및 .NET Framework 4.7.2를 대상으로 하지만 PackageA
더 이상 최신 버전에서 .NET Standard 2.0을 지원하지 않는 경우 각 대상 프레임워크에 대해 다른 버전을 지정할 수 있습니다.
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFrameworks>netstandard2.0;net8.0;net472</TargetFrameworks>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="PackageA" />
</ItemGroup>
</Project>
이 경우 Directory.Packages.props
사용하여 각 대상 프레임워크에 대해 서로 다른 버전을 정의합니다.
<Project>
<PropertyGroup>
<ManagePackageVersionsCentrally>true</ManagePackageVersionsCentrally>
</PropertyGroup>
<ItemGroup>
<PackageVersion Include="PackageA" Version="1.0.0" Condition="'$(TargetFramework)' == 'netstandard2.0'" />
<PackageVersion Include="PackageA" Version="2.0.0" Condition="'$(TargetFramework)' == 'net8.0' Or '$(TargetFramework)' == 'net472'" />
</ItemGroup>
</Project>
전이적 고정
전이적 고정이라는 기능을 옵트인하여 명시적 최상위 <PackageReference />
항목 없이 전이적 패키지 버전을 자동으로 재정의할 수 있습니다.
이렇게 하면 필요한 경우 전이적 종속성을 사용자 대신 암시적으로 최상위 종속성으로 승격합니다.
패키지를 전이적으로 고정할 때는 다운그레이드가 허용되지 않습니다. 종속성에서 요청한 것보다 낮은 버전으로 패키지를 고정하려고 하면 복원하면 NU1109 오류가 발생합니다.
프로젝트나 CentralPackageTransitivePinningEnabled
, true
가져오기 파일에서 MSBuild 속성 Directory.Packages.props
를 Directory.Build.props
로 설정하여 이 기능을 활성화할 수 있습니다.
<PropertyGroup>
<CentralPackageTransitivePinningEnabled>true</CentralPackageTransitivePinningEnabled>
</PropertyGroup>
전이성 고정 및 패키지
패키지가 전이적으로 고정되면 프로젝트는 종속성에서 요청한 버전보다 높은 버전을 사용합니다. 프로젝트에서 패키지를 만드는 경우 패키지가 작동하는지 확인하기 위해 NuGet은 전이적으로 고정된 종속성을 nuspec의 명시적 종속성으로 승격합니다.
다음 예제에서는 PackageA 1.0.0
PackageB 1.0.0
대한 종속성을 가합니다.
<Project>
<ItemGroup>
<PackageVersion Include="PackageA" Version="1.0.0" />
<PackageVersion Include="PackageB" Version="2.0.0" />
</ItemGroup>
</Project>
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<CentralPackageTransitivePinningEnabled>true</CentralPackageTransitivePinningEnabled>
<TargetFramework>net6.0</TargetFramework>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="PackageA" />
</ItemGroup>
</Project>
pack 명령을 사용하여 패키지를 만들면 두 패키지가 모두 종속성 그룹에 표시됩니다.
<group targetFramework="net6.0">
<dependency id="PackageA" version="1.0.0" exclude="Build,Analyzers" />
<dependency id="PackageB" version="2.0.0" exclude="Build,Analyzers" />
</group>
이 때문에 라이브러리를 작성할 때는 예상하지 못한 종속성으로 이어질 수 있으므로 전이적 고정 사용을 신중하게 평가해야 합니다.
패키지 버전 덮어쓰기
VersionOverride
항목의 <PackageReference />
속성을 사용하여 개별 패키지 버전을 재정의할 수 있습니다.
이는 중앙에서 정의된 <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>
프로젝트 또는 CentralPackageVersionOverrideEnabled
또는 false
가져오기 파일에서 MSBuild 속성 Directory.Packages.props
을 Directory.Build.props
로 설정하여 이 기능을 비활성화할 수 있습니다.
<PropertyGroup>
<CentralPackageVersionOverrideEnabled>false</CentralPackageVersionOverrideEnabled>
</PropertyGroup>
이 기능을 사용하지 않도록 설정하면 VersionOverride
항목에 <PackageReference />
지정하면 복원 시 기능이 비활성화되었음을 나타내는 오류가 발생합니다.
중앙 패키지 관리 비활성화
특정 프로젝트에 대해 중앙 패키지 관리를 사용하지 않도록 설정하려면 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 경고
중앙 패키지 관리를 사용하는 경우 NuGet은 구성에 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.