다음을 통해 공유


NuGet에서 패키지 종속성을 확인하는 방법

복원 프로세스의 일부로 설치되는 것을 포함하여 패키지를 설치하거나 다시 설치할 때마다 NuGet은 첫 번째 패키지가 의존하는 추가 패키지도 설치합니다.

이러한 즉각적인 종속성에는 자체적인 종속성도 있을 수 있으며, 이는 임의의 깊이로 계속 진행될 수 있습니다. 이렇게 하면 모든 수준에서 패키지 간의 관계를 설명하는 종속성 그래프 생성됩니다.

여러 패키지에 동일한 종속성이 있는 경우 동일한 패키지 ID가 그래프에 여러 번 표시될 수 있으며, 잠재적으로 버전 제약 조건이 다를 수 있습니다. 그러나 프로젝트에서는 지정된 패키지의 버전 하나만 사용할 수 있으므로 NuGet에서 사용되는 버전을 선택해야 합니다. 정확한 프로세스는 사용 중인 패키지 관리 형식에 따라 달라집니다.

PackageReference를 사용하여 종속성 확인

PackageReference 형식을 사용하여 프로젝트에 패키지를 설치할 때 NuGet은 적절한 파일의 플랫 패키지 그래프에 참조를 추가하고 충돌을 미리 해결합니다. 이 프로세스를 전이적 복원이라고 합니다. 그런 다음, 패키지를 다시 설치하거나 복원하는 프로세스는 그래프에 나열된 패키지를 다운로드하여 더 빠르고 예측 가능한 빌드를 생성합니다.

2.8.*과 같은 부동 버전을 활용하여 최신 버전의 패키지를 사용하도록 프로젝트를 수정하지 않도록 할 수도 있습니다. 부동 버전을 사용하는 경우 반복성을 보장하기 위해 잠금 파일 기능 사용하도록 설정하는 것이 좋습니다.

빌드 전에 NuGet 복원 프로세스가 실행되면 먼저 메모리에서 종속성을 해결한 다음 결과 그래프를 project.assets.json파일에 씁니다.

자산 파일은 기본적으로 프로젝트의 'obj' 폴더에 위치한 MSBuildProjectExtensionsPath에 있습니다. 그런 다음 MSBuild는 이 파일을 읽고 잠재적 참조를 찾을 수 있는 폴더 집합으로 변환한 다음 메모리의 프로젝트 트리에 추가합니다.

project.assets.json 파일은 일시적이므로 소스 제어에 추가해서는 안 됩니다. 기본적으로 .gitignore.tfignore모두 나열됩니다. 패키지 및 소스 제어참조하세요.

종속성 해결 규칙

전이적 복원은 종속성을 해결하기 위해 네 가지 주요 규칙을 적용합니다: 가장 낮은 적용 가능한 버전, 부동 버전, 직접 종속성 우선사촌 종속성.

가장 낮은 적용 가능한 버전

가장 낮은 적용 가능한 버전 규칙은 해당 종속성으로 정의된 패키지의 가능한 가장 낮은 버전을 복원합니다. 부동선언하지 않는 한 애플리케이션 또는 클래스 라이브러리에 대한 종속성에도 적용됩니다.

예를 들어 다음 그림에서 1.0 베타는 1.0보다 낮은 것으로 간주되므로 NuGet은 1.0 버전을 선택합니다.

적용 가능한 가장 낮은 버전 선택

다음 그림에서 버전 2.1은 피드에서 사용할 수 없지만 버전 제약 조건이 >= 2.1 NuGet은 찾을 수 있는 다음으로 가장 낮은 버전을 선택합니다(이 경우 2.2).

피드에서 사용할 수 있는 다음으로 가장 낮은 버전 선택

애플리케이션이 피드에서 사용할 수 없는 정확한 버전 번호(예: 1.2)를 지정하면 패키지를 설치하거나 복원하려고 할 때 NuGet이 오류와 함께 실패합니다.

NuGet은 정확한 패키지 버전을 사용할 수 없는 경우 오류를 생성합니다

유동적인 버전

부동 종속성 버전은 * 문자로 지정됩니다. 예를 들어 6.0.*. 이 버전 사양에는 "최신 6.0.x 버전 사용"이 표시됩니다. 4.* "최신 4.x 버전 사용"을 의미합니다. 부동 버전을 사용하면 최신 버전의 종속성을 유지하면서 프로젝트 파일의 변경 내용을 줄일 수 있습니다. 부동 버전은 프로젝트 수준에서만 지정할 수 있습니다.

부동 버전을 사용하는 경우 NuGet은 버전 패턴과 일치하는 패키지의 가장 높은 버전을 확인합니다. 예를 들어 6.0.* 6.0으로 시작하는 패키지의 가장 높은 버전을 가져옵니다.

부동 버전 6.0.*이 요청된 경우 버전 6.0.1 선택

버전 서버에 있는 버전 해상도 이유 노트
* 1.1.0
1.1.1
1.2.0
1.3.0-alpha
1.2.0 가장 안정적인 버전입니다.
1.1.* 1.1.0
1.1.1
1.1.2-alpha
1.2.0-alpha
1.1.1 지정된 패턴을 준수하는 가장 안정적인 버전입니다.
*-* 1.1.0
1.1.1
1.1.2-alpha
1.3.0-beta
1.3.0-beta 안정적이지 않은 버전을 포함하는 가장 높은 버전입니다. Visual Studio 버전 16.6, NuGet 버전 5.6, .NET Core SDK 버전 3.1.300에서 사용 가능
1.1.*-* 1.1.0
1.1.1
1.1.2-alpha
1.1.2-beta
1.3.0-beta
1.1.2-beta 패턴을 준수하고 안정적이지 않은 버전을 포함하는 가장 높은 버전입니다. Visual Studio 버전 16.6, NuGet 버전 5.6, .NET Core SDK 버전 3.1.300에서 사용 가능
1.2.0-rc.* 1.1.0
1.2.0-rc.1
1.2.0-rc.2
1.2.0
1.2.0 시험판 부분이 포함된 버전 범위임에도 불구하고, 안정적인 부분과 일치할 경우 안정적인 버전이 허용됩니다. 1.2.0 > 1.2.0-rc.2가 선택됩니다.

메모

유동적 버전 해결은 패키지 나열 여부를 고려하지 않습니다. 조건이 전역 패키지 폴더의 패키지로 충족될 수 있는 경우 유동적 버전 해석이 로컬에서 해결됩니다.

직접 종속성 우선

애플리케이션에 대한 패키지 그래프에 동일한 하위 그래프에 패키지의 다른 버전이 포함되어 있고 해당 버전 중 하나가 해당 하위 그래프의 직접 종속성인 경우 해당 버전은 해당 하위 그래프에 대해 선택되고 나머지는 무시됩니다. 이 동작을 사용하면 애플리케이션이 종속성 그래프의 특정 패키지 버전을 재정의할 수 있습니다.

아래 예제에서 애플리케이션은 버전 제약 조건이 >=2.0.0인 패키지 B에 직접 의존합니다. 애플리케이션은 패키지 A에 의존하며, 패키지 A는 다시 패키지 B에 의존하지만 >=1.0.0의 제약 조건이 있습니다. 패키지 B 2.0.0에 대한 종속성은 그래프의 애플리케이션에 대한 직접 종속성이므로 해당 버전이 사용됩니다.

직접 종속성 승리 규칙을 사용하는 애플리케이션

경고

직접 종속성 우선 규칙으로 인해 패키지 버전이 다운그레이드되어 그래프의 다른 종속성이 손상될 수 있습니다. 패키지가 다운그레이드되면 NuGet은 사용자를 경고하기 위해 경고를 추가합니다..

또한 이 규칙은 큰 종속성 그래프를 사용하여 효율성을 높입니다. 동일한 하위 그래프의 종속성이 더 높은 버전보다 높은 경우 NuGet은 해당 종속성을 무시하고 NuGet은 그래프의 해당 분기에 남아 있는 모든 종속성을 무시합니다.

예를 들어 아래 다이어그램에서 패키지 C 2.0.0이 사용되므로 NuGet은 이전 버전의 패키지 C를 참조하는 하위 그래프의 모든 분기를 무시합니다.

NuGet이 그래프의 패키지를 무시하면 전체 분기가 무시됩니다

이 규칙을 통해 NuGet은 패키지 작성자의 의도를 적용하려고 합니다. 아래 다이어그램에서 패키지 A의 작성자가 명시적으로 패키지 C 2.0.0에서 패키지 C 1.0.0으로 다운그레이드했습니다.

패키지 작성자가 명시적으로 다운그레이드하면 NuGet에서 이를 적용합니다.

애플리케이션 소유자는 패키지 C를 2.0.0보다 높은 버전으로 업그레이드하도록 선택할 수 있으므로 패키지 C에 대한 버전을 더 이상 다운그레이드할 수 없습니다. 이 경우 경고가 발생하지 않습니다.

애플리케이션이 다운그레이드된 패키지에 대한 직접 종속성을 추가하면, NuGet은 이를 준수합니다.

사촌 종속성

애플리케이션과 그래프의 다른 하위 그래프에서 다른 패키지 버전을 참조하는 경우 NuGet은 모든 버전 요구 사항을 충족하는 가장 낮은 버전을 사용합니다(가장 낮은 적용 가능한 버전부동 버전 규칙과 같이). 예를 들어 아래 이미지에서 패키지 B의 버전 2.0.0은 다른 >=1.0.0 제약 조건을 충족하므로 다음과 같이 사용됩니다.

모든 제약 조건을 충족하는 하위 버전을 사용하여 사촌 종속성 해결

사촌 종속성 규칙을 적용하기 위해 패키지가 동일한 거리에 있을 필요는 없습니다. 아래 다이어그램에서 패키지 D 2.0.0은 패키지 C 하위 그래프에서 선택되고 패키지 D 3.0.0은 패키지 A의 하위 그래프에서 선택됩니다. 애플리케이션 하위 그래프에는 패키지 D에 대한 직접 종속성이 없으므로 가장 낮은 적용 가능한 버전 규칙이 적용되고 버전 3.0.0이 선택됩니다.

다른 거리에서 모든 제약 조건을 충족하는 하위 버전을 사용하여 사촌 종속성 해결

경우에 따라 모든 버전 요구 사항을 충족할 수 없습니다. 아래와 같이 패키지 A에 정확히 패키지 B 1.0.0이 필요하고 패키지 C에 패키지 B >=2.0.0이 필요한 경우 NuGet에서 종속성을 해결할 수 없고 오류가 발생합니다.

정확한 버전 요구 사항으로 인해 수정할 수 없는 종속성이

이러한 상황에서는 최상위 소비자(애플리케이션 또는 패키지)가 패키지 B에 대한 직접 종속성을 추가하여 직접 종속성이 규칙에 따라 우선 적용되도록 해야 합니다.

PackageReference를 사용하는 버전 범위 및 시험판 버전

패키지에서 안정적인 버전과 시험판 버전을 모두 사용할 수 있는 것은 드문 일이 아닙니다. 종속성 그래프를 확인할 때 NuGet은 단일 규칙에 따라 패키지의 시험판 버전을 고려할지 여부를 결정합니다. If the project or any packages within the graph request a prerelease version of a package, then include both prerelease or stable versions, otherwise consider stable versions only.

실제로 가장 낮은 적용 가능한 규칙에 따라 다음을 의미합니다.

버전 범위 사용 가능한 버전 선택한 버전
[1.0.0, 2.0.0) 1.2.0-beta.1, 1.2.0, 1.2.0
[1.0.0, 2.0.0-0) 1.2.0-beta.1, 1.2.0, 1.2.0-beta.1
[1.0.0, 2.0.0) 1.2.0-beta.1, 2.0.0-beta.3 없음, NU1103 발생합니다.
[1.0.0, 2.0.0-rc) 1.2.0-beta.1, 2.0.0-beta.3 1.2.0-beta.1

packages.config 사용하여 종속성 해결

packages.config을 사용하면 프로젝트의 종속성이 플랫 목록으로 packages.config에 쓰여집니다. 이러한 패키지의 종속성도 동일한 목록에 기록됩니다. 패키지가 설치되면 NuGet은 .csproj 파일, app.config, web.config및 기타 개별 파일을 수정할 수도 있습니다.

packages.config을 사용하여 NuGet은 각 개별 패키지를 설치하는 동안 종속성 충돌을 해결하려고 시도합니다. 즉, 패키지 A가 설치되고 있고 패키지 B에 종속되어 있고 패키지 B가 이미 packages.config 다른 항목의 종속성으로 나열된 경우 NuGet은 요청되는 패키지 B의 버전을 비교하고 모든 버전 제약 조건을 충족하는 버전을 찾으려고 시도합니다. 특히 NuGet은 종속성을 충족하는 하위 major.minor 버전을 선택합니다.

기본적으로 NuGet 2.8은 가장 낮은 패치 버전을 찾습니다(NuGet 2.8 릴리스 정보참조). NuGet.Config DependencyVersion 특성과 명령줄의 -DependencyVersion 스위치를 통해 이 설정을 제어할 수 있습니다.

종속성을 확인하기 위한 packages.config 프로세스는 더 큰 종속성 그래프에 대해 복잡해집니다. 각 새 패키지 설치에는 전체 그래프를 통과해야 하며 버전 충돌이 발생할 가능성이 높아질 수 있습니다. 충돌이 발생하면 설치가 중지되어 프로젝트가 확정되지 않은 상태로 남게 되며, 특히 프로젝트 파일 자체를 수정할 가능성이 있습니다. 다른 패키지 관리 형식을 사용할 때는 문제가 되지 않습니다.

packages.config 있는 버전 범위 및 시험판 버전

packages.config 해상도는 그래프에서 안정적인 종속성과 사전 릴리스 종속성을 혼합하는 것을 허용하지 않습니다. 종속성이 [1.0.0, 2.0.0)같은 범위로 표현되면 그래프에서 시험판 패키지가 허용되지 않습니다.

종속성 자산 관리

PackageReference 형식을 사용하는 경우 종속성에서 최상위 프로젝트로 흐르는 자산을 제어할 수 있습니다. 자세한 내용은 PackageReference참조하세요.

최상위 프로젝트 자체가 패키지인 경우 .nuspec 파일에 나열된 종속성이 있는 includeexclude 특성을 사용하여 이 흐름을 제어할 수도 있습니다. .nuspec 참조 - 종속성을 참조하세요.

참조 제외

프로젝트에서 이름이 같은 어셈블리를 두 번 이상 참조하여 디자인 타임 및 빌드 시간 오류를 생성하는 시나리오가 있습니다. 사용자 지정 버전의 C.dll포함하고 C.dll포함하는 패키지 C를 참조하는 프로젝트를 고려합니다. 동시에 프로젝트는 패키지 C와 C.dll에 의존하는 패키지 B에 의존합니다. 따라서 NuGet은 사용할 C.dll 확인할 수 없지만 패키지 B도 패키지 C에 종속되어 있으므로 프로젝트의 C 종속성을 제거할 수 없습니다.

이 문제를 해결하려면 원하는 C.dll 직접 참조(또는 올바른 패키지를 참조하는 다른 패키지를 사용)한 다음 모든 자산을 제외하는 패키지 C에 대한 종속성을 추가해야 합니다. 이 작업은 사용 중인 패키지 관리 형식에 따라 다음과 같이 수행됩니다.

  • PackageReference: 종속성에 ExcludeAssets="All" 추가합니다.

    <PackageReference Include="PackageC" Version="1.0.0" ExcludeAssets="All" />
    
  • packages.config: .csproj 파일에서 PackageC에 대한 참조를 제거하여 원하는 C.dll 버전만 참조하도록 합니다.

패키지 설치 중 종속성 업데이트

종속성 버전이 이미 충족되면 다른 패키지 설치 중에 종속성이 업데이트되지 않습니다. 예를 들어 패키지 B에 따라 버전 번호에 대해 1.0을 지정하는 패키지 A를 고려합니다. 원본 리포지토리에는 패키지 B의 버전 1.0, 1.1 및 1.2가 포함됩니다. 이미 B 버전 1.0이 포함된 프로젝트에 A가 설치된 경우 B 1.0은 버전 제약 조건을 충족하므로 계속 사용 중입니다. 그러나 패키지 A에 B 버전 1.1 이상을 요청하는 경우 B 1.2가 설치됩니다.

호환되지 않는 패키지 오류 해결

패키지 복원 작업 중에 "하나 이상의 패키지가 호환되지 않습니다..."라는 오류가 표시 될 수 있습니다. 또는 패키지가 프로젝트의 대상 프레임워크와 "호환되지 않습니다".

이 오류는 프로젝트에서 참조되는 패키지 중 하나 이상이 프로젝트의 대상 프레임워크를 지원한다는 것을 나타내지 않을 때 발생합니다. 즉, 패키지에는 프로젝트와 호환되는 대상 프레임워크의 lib 폴더에 적합한 DLL이 포함되어 있지 않습니다. 대상 프레임워크의 목록을 참조하세요.

예를 들어 프로젝트가 netstandard1.6 대상으로 지정하고 lib\net20\lib\net45 폴더에만 DLL이 포함된 패키지를 설치하려고 하면 패키지 및 해당 종속 항목에 대해 다음과 같은 메시지가 표시됩니다.

Restoring packages for myproject.csproj...
Package ContosoUtilities 2.1.2.3 is not compatible with netstandard1.6 (.NETStandard,Version=v1.6). Package ContosoUtilities 2.1.2.3 supports:
  - net20 (.NETFramework,Version=v2.0)
  - net45 (.NETFramework,Version=v4.5)
Package ContosoCore 0.86.0 is not compatible with netstandard1.6 (.NETStandard,Version=v1.6). Package ContosoCore 0.86.0 supports:
  - 11 (11,Version=v0.0)
  - net20 (.NETFramework,Version=v2.0)
  - sl3 (Silverlight,Version=v3.0)
  - sl4 (Silverlight,Version=v4.0)
One or more packages are incompatible with .NETStandard,Version=v1.6.
Package restore failed. Rolling back package changes for 'MyProject'.

비호환성을 해결하려면 다음 중 하나를 수행합니다.

  • 사용하려는 패키지에서 지원하는 프레임워크로 프로젝트의 대상을 변경합니다.
  • 패키지 작성자에게 문의하고 패키지와 협력하여 선택한 프레임워크에 대한 지원을 추가합니다. nuget.org 각 패키지 목록 페이지에는 이 목적을 위한 연락처 소유자 링크가 있습니다.

대체 솔루션: NuGetSolver는 종속성 충돌 해결을 지원하도록 설계된 Microsoft DevLabs에서 개발한 Visual Studio 확장입니다. 이러한 문제를 식별하고 해결하는 프로세스를 자동화합니다. 자세한 내용은 Visual Studio Marketplace의 NuGetSolver 페이지를 방문하여 사용자 환경에 대한 피드백을 듣고 싶습니다.