다음을 통해 공유


.NET 9용 SDK 및 도구의 새로운 기능

이 문서에서는 .NET SDK 및 .NET 9용 도구의 새로운 기능에 대해 설명합니다.

단위 테스트

이 섹션에서는 .NET 9의 단위 테스트 업데이트, 즉 병렬로 테스트 실행 및 터미널 로거 테스트 출력에 대해 설명합니다.

병렬로 테스트 실행

.NET 9에서는 dotnet test MSBuild와 완전히 통합됩니다. MSBuild는 병렬 빌드를 지원하므로 여러 대상 프레임워크에서 동일한 프로젝트에 대한 테스트를 병렬로 실행할 수 있습니다. 기본적으로 MSBuild는 병렬 프로세스 수를 컴퓨터의 프로세서 수로 제한합니다. -maxcpucount 스위치를 사용하여 사용자 고유의 제한을 설정할 수도 있습니다. 병렬 처리를 옵트아웃하려면 TestTfmsInParallel MSBuild 속성을 false설정합니다.

터미널 로거 테스트 표시

테스트 결과 보고 기능은 이제 MSBuild 터미널 로거에서 직접 지원됩니다. 테스트가 실행되는 동안( 보고하고 실행 중인 테스트 이름을 표시) 및 테스트가 완료된 후( 모든 테스트 오류가 더 나은 방식으로 렌더링됨) 더 완전한 기능의 테스트 보고서를 받을 수 있습니다.

터미널 로거에 대한 자세한 내용은 dotnet 빌드 옵션을 참조하세요.

.NET 도구 전진

.NET 도구 전역 또는 로컬로 설치한 다음 .NET SDK 및 설치된 .NET 런타임을 사용하여 실행할 수 있는 프레임워크 종속 앱입니다. 모든 .NET 앱과 같은 이러한 도구는 특정 주 버전의 .NET을 대상으로 합니다. 기본적으로 앱은 최신 버전의 .NET에서 실행되지 않습니다. 도구 작성자는 RollForward MSBuild 속성을 설정하여 최신 버전의 .NET 런타임에서 도구를 실행하도록 옵트인할 수 있었습니다. 그러나 모든 도구가 그렇게 하는 것은 아닙니다.

dotnet tool install에 대한 새로운 옵션을 통해 사용자가 .NET 도구를 실행하는 방법을 결정할 수 있습니다. dotnet tool install통해 도구를 설치하거나 dotnet tool run <toolname>통해 도구를 실행할 때 --allow-roll-forward이라는 새 플래그를 지정할 수 있습니다. 이 옵션은 도구를 롤 포워드 모드 Major로 구성합니다. 이 모드를 사용하면 일치하는 .NET 버전을 사용할 수 없는 경우 최신 주 버전의 .NET에서 도구를 실행할 수 있습니다. 이 기능을 사용하면 얼리어답터에서 도구 작성자가 코드를 변경하지 않고도 .NET 도구를 사용할 수 있습니다.

터미널 로거

이제 터미널 로거가 기본적으로 사용하도록 설정되어 있으며 유용성도 향상되었습니다.

기본적으로 사용

.NET 9부터 MSBuild를 사용하는 모든 .NET CLI 명령에 대한 기본 환경은 .NET 8에서 릴리스된 향상된 로깅 환경인 터미널 로거입니다. 이 새 출력은 최신 터미널의 기능을 사용하여 다음과 같은 기능을 제공합니다.

  • 클릭 가능한 링크
  • MSBuild 작업에 대한 기간 타이머
  • 경고 및 오류 메시지의 색 코딩

출력은 기존 MSBuild 콘솔 로거보다 더 압축되고 사용할 수 있습니다.

새 로거는 사용할 수 있는지 자동 검색을 시도하지만 터미널 로거가 사용되는지 여부를 수동으로 제어할 수도 있습니다. 특정 명령에 대해 --tl:off 터미널 로거를 사용하지 않도록 설정하는 명령줄 옵션을 지정합니다. 터미널 로거를 비활성화하려면 환경 변수를 MSBUILDTERMINALLOGGER로 설정하십시오.

기본적으로 터미널 로거를 사용하는 명령 집합은 다음과 같습니다.

  • build
  • clean
  • msbuild
  • pack
  • publish
  • restore
  • test

사용성

이제 터미널 로거는 빌드 종료 시 총 오류 및 경고 수를 요약합니다. 행바꿈이 포함된 오류도 표시합니다. 터미널 로거에 대한 자세한 내용은 'dotnet build' 옵션, 특히 --tl 옵션을 참조하세요.

프로젝트를 빌드할 때 경고를 내보내는 다음 프로젝트 파일을 고려합니다.

<Project Sdk="Microsoft.NET.Sdk">

  <PropertyGroup>
    <TargetFramework>net8.0</TargetFramework>
  </PropertyGroup>

  <Target Name="Error" BeforeTargets="Build">
    <Warning Code="ECLIPSE001" Text="Black Hole Sun, won't you come
  And wash away the rain
    Black Hole Sun, won't you come
      won't you come" />
  </Target>
</Project>

.NET 8 SDK에서 dotnet build -tl 실행하는 경우 출력은 이 단락 뒤에 나와 있습니다. 여러 줄 경고의 각 줄은 읽기 어려운 출력에 전체 오류 메시지 접두사를 포함하는 별도의 줄입니다. 또한 최종 빌드 요약에 따르면 경고가 있지만 수는 않습니다. 누락된 정보는 특정 빌드가 이전 빌드보다 더 나은지 또는 더 나쁜지 확인하기 어렵게 만들 수 있습니다.

$ dotnet build -tl
MSBuild version 17.8.5+b5265ef37 for .NET
Restore complete (0.5s)
  multiline-error-example succeeded with warnings (0.2s) → bin\Debug\net8.0\multiline-error-example.dll
    E:\Code\multiline-error-example.csproj(11,5): warning ECLIPSE001: Black Hole Sun, won't you come
E:\Code\multiline-error-example.csproj(11,5): warning ECLIPSE001:   And wash away the rain
E:\Code\multiline-error-example.csproj(11,5): warning ECLIPSE001:     Black Hole Sun, won't you come
E:\Code\multiline-error-example.csproj(11,5): warning ECLIPSE001:       won't you come
Build succeeded with warnings in 0.9s

.NET 9 SDK를 사용하여 동일한 프로젝트를 빌드하는 경우 출력은 다음과 같습니다.

> dotnet build -tl
Restore complete (0.4s)
You are using a preview version of .NET. See: https://aka.ms/dotnet-support-policy
  multiline-error-example succeeded with 3 warning(s) (0.2s) → bin\Debug\net8.0\multiline-error-example.dll
    E:\Code\multiline-error-example.csproj(11,5): warning ECLIPSE001:
      Black Hole Sun, won't you come
        And wash away the rain
          Black Hole Sun, won't you come
            won't you come
Build succeeded with 3 warning(s) in 0.8s

경고의 메시지 줄에는 더 이상 디스플레이를 어지럽히는 반복된 프로젝트 및 위치 정보가 없습니다. 또한 빌드 요약에서는 빌드 중에 생성된 경고 수(및 오류가 있는 경우)를 보여 줍니다.

터미널 로거에 대한 피드백이 있는 경우 MSBuild 리포지토리에서 제공할 수 있습니다.

대규모 리포지토리의 NuGet 종속성 처리 속도 향상

NuGet 종속성 확인자는 모든 <PackageReference> 프로젝트의 성능과 확장성을 개선하기 위해 철저히 검사되었습니다. 기본적으로 사용하도록 설정된 새 알고리즘은 핵심 종속성 확인 규칙을 엄격하게 준수하면서 기능을 손상시키지 않고 복원 작업을 가속화합니다.

복원 실패 또는 예기치 않은 패키지 버전과 같은 문제가 발생하는 경우 레거시 해결 프로그램 되돌릴 수 있습니다.

MSBuild 스크립트 분석기("BuildChecks")

.NET 9에는 빌드 스크립트의 결함 및 회귀를 방지할 수 있는 기능이 도입되었습니다. 빌드 검사를 실행하려면 MSBuild를 호출하는 명령에 /check 플래그를 추가합니다. 예를 들어 dotnet build myapp.sln /checkmyapp 솔루션을 빌드하고 구성된 모든 빌드 검사를 실행합니다.

.NET 9 SDK에는 몇 가지 초기 검사로 예를 들어, BC0101BC0102이 포함되어 있습니다. 전체 목록은 BuildCheck 코드참조하세요.

문제가 감지되면 문제가 포함된 프로젝트의 빌드 출력에서 진단이 생성됩니다.

자세한 내용은 디자인 설명서참조하세요.

분석기 불일치

많은 사용자가 .NET SDK 및 Visual Studio를 다양한 주기로 설치합니다. 이러한 유연성은 바람직하지만 두 환경 간에 상호 운용해야 하는 도구에 문제가 발생할 수 있습니다. 이러한 종류의 도구의 한 가지 예는 Roslyn 분석기입니다. 분석기 작성자는 Roslyn의 특정 버전에 대해 코딩해야 하지만 사용 가능한 버전과 지정된 빌드에서 사용되는 버전은 때때로 불분명합니다.

.NET SDK와 MSBuild 간의 이러한 종류의 버전 불일치는 분리된 SDK라고 합니다. 이 상태인 경우 다음과 같은 오류가 표시될 수 있습니다.

CSC: 경고 CS9057: 분석기 어셈블리 '..\dotnet\sdk\8.0.200\Sdks\Microsoft.NET.Sdk.Razor\source-generators\Microsoft.CodeAnalysis.Razor.Compiler.SourceGenerators.dll'는 현재 실행 중인 버전 '4.8.0.0'보다 최신 컴파일러의 버전 '4.9.0.0'을 참조합니다.

.NET 9는 이 문제 시나리오를 감지하고 자동으로 조정할 수 있습니다. SDK의 MSBuild 논리에는 제공된 MSBuild 버전이 포함되며, 해당 정보를 사용하여 SDK가 다른 버전의 환경에서 실행되는 시기를 감지할 수 있습니다. 이 경우 SDK는 일관된 분석기 환경을 보장하는 Microsoft.Net.Sdk.Compilers.Toolset이라는 지원 패키지의 암시적 다운로드를 삽입합니다.

워크로드 세트

워크로드 집합 설치하는 워크로드 및 해당 워크로드의 변경 주기를 사용자에게 더 자세히 제어할 수 있는 SDK 기능입니다. 이전 버전에서는 구성된 NuGet 피드에 새 버전의 개별 워크로드가 릴리스됨에 따라 워크로드가 주기적으로 업데이트되었습니다. 이제 명시적 업데이트 제스처를 취할 때까지 모든 워크로드가 특정 단일 버전에 머뭅니다.

dotnet workload --info실행하여 SDK 설치의 모드를 확인할 수 있습니다.

> dotnet workload --info
Workload version: 9.0.100-manifests.400dd185
Configured to use loose manifests when installing new manifests.
 [aspire]
   Installation Source: VS 17.10.35027.167, VS 17.11.35111.106
   Manifest Version:    8.0.2/8.0.100
   Manifest Path:       C:\Program Files\dotnet\sdk-manifests\8.0.100\microsoft.net.sdk.aspire\8.0.2\WorkloadManifest.json
   Install Type:              Msi

이 예제에서 SDK 설치는 '매니페스트' 모드로, 업데이트가 사용 가능한 대로 설치됩니다. 새 모드를 옵트인하려면 --version 또는 dotnet workload install 명령에 dotnet workload update 옵션을 추가합니다. 새 dotnet workload config 명령을 사용하여 작업 모드를 명시적으로 제어할 수도 있습니다.

> dotnet workload config --update-mode workload-set
Successfully updated workload install mode to use workload-set.

어떤 이유로든 다시 변경해야 하는 경우 manifests대신 workload-set 사용하여 동일한 명령을 실행할 수 있습니다. dotnet workload config --update-mode 사용하여 현재 작업 모드를 확인할 수도 있습니다.

자세한 내용은 .NET SDK 워크로드 집합 참조하세요.

워크로드 기록

.NET SDK 워크로드는 .NET MAUI 및 Blazor WebAssembly의 필수적인 부분입니다. 기본 구성에서는 .NET 도구 작성자가 새 버전을 릴리스할 때 워크로드를 독립적으로 업데이트할 수 있습니다. 또한 Visual Studio를 통해 수행된 .NET SDK 설치는 병렬 버전 집합을 설치합니다. 주의하지 않고 지정된 .NET SDK 설치의 워크로드 설치 상태는 시간이 지남에 따라 드리프트될 수 있지만 이 드리프트를 시각화하는 방법은 없습니다.

이 문제를 해결하기 위해 .NET 9는 .NET SDK에 새 dotnet workload history 명령을 추가합니다. dotnet workload history 현재 .NET SDK 설치에 대한 워크로드 설치 기록 및 수정 내용의 표를 출력합니다. 이 표에서는 설치 또는 수정 날짜, 실행된 명령, 설치 또는 수정된 워크로드 및 명령에 대한 관련 버전을 보여 줍니다. 이 출력은 시간이 지남에 따라 워크로드 설치의 드리프트를 이해하는 데 도움이 되며 설치를 설정할 워크로드 버전에 대해 정보에 입각한 결정을 내리는 데 도움이 됩니다. git reflog를 워크로드의 기준으로 생각할 수 있습니다.

> dotnet workload history

Id  Date                         Command       Workloads                                        Global.json Version  Workload Version
-----------------------------------------------------------------------------------------------------------------------------------------------
1   1/1/0001 12:00:00 AM +00:00  InitialState  android, ios, maccatalyst, maui-windows                               9.0.100-manifests.6d3c8f5d
2   9/4/2024 8:15:33 PM -05:00   install       android, aspire, ios, maccatalyst, maui-windows                       9.0.100-rc.1.24453.3

이 예제에서 SDK는 처음에 android, ios, maccatalystmaui-windows 워크로드와 함께 설치되었습니다. 그런 다음 dotnet workload install aspire --version 9.0.100-rc.1.24453.3 명령을 사용하여 aspire 워크로드를 설치한 후, 워크로드 집합 모드를 로 전환하고모드로 설정했습니다. 이전 상태로 돌아가려면 기록 테이블의 첫 번째 열에 있는 ID(예: dotnet workload update --from-history 1)를 사용할 수 있습니다.

컨테이너

안전하지 않은 레지스트리에 대한 게시 지원

SDK의 기본 제공 컨테이너 게시 지원은 컨테이너 레지스트리에 이미지를 게시할 수 있습니다. .NET 9까지 해당 레지스트리를 보호해야 했습니다. .NET SDK가 작동하려면 HTTPS 지원 및 유효한 인증서가 필요했습니다. 컨테이너 엔진은 일반적으로 안전하지 않은 레지스트리, 즉 TLS가 구성되지 않았거나 TLS가 잘못된 인증서로 구성된 레지스트리에서도 작동하도록 구성할 수 있습니다. 이는 유효한 사용 사례이지만 도구에서 이 통신 모드를 지원하지 않았습니다.

.NET 9부터 SDK는 안전하지 않은 레지스트리와 통신할 수 있습니다.

요구 사항(사용자 환경에 따라 다름):

  • 레지스트리를 안전하지 않은 것으로 표시하도록 Docker CLI를 구성합니다.
  • 레지스트리를 안전하지 않은 것으로 표시하도록 Podman을 구성합니다.
  • DOTNET_CONTAINER_INSECURE_REGISTRIES 환경 변수를 사용하여 안전하지 않은 것으로 처리할 레지스트리 도메인의 세미콜론으로 구분된 목록을 전달합니다.

환경 변수 이름 지정

컨테이너 게시 도구에서 레지스트리 통신 및 보안의 몇 가지 세부적인 측면을 제어하는 데 사용하는 환경 변수는 이제 DOTNET대신 접두사 SDK 시작합니다. SDK 접두사는 단기적으로 계속 지원됩니다.

코드 분석

.NET 9에는 .NET 라이브러리 API를 정확하고 효율적으로 사용하고 있는지 확인하는 데 도움이 되는 몇 가지 새로운 코드 분석기 및 수정기가 포함되어 있습니다. 다음 표에서는 새 분석기를 요약합니다.

규칙 ID 범주 묘사
CA1514: 중복 길이 인수를 피하십시오 유지 관리 명시적으로 계산된 길이 인수는 오류가 발생하기 쉬울 수 있으며 문자열 또는 버퍼의 끝으로 조각화할 때는 필요하지 않습니다.
CA1515: 공용 형식을 내부적 형식으로 만드는 것을 고려하십시오. 유지 관리 실행 파일 어셈블리 내의 형식은 internal선언해야 합니다.
CA1871: null을 허용하는 구조체를 'ArgumentNullException.ThrowIfNull'에 전달하지 마십시오. 성능 성능을 향상시키려면 null 허용 구조체를 HasValue전달하는 것보다 ArgumentNullException.ThrowIfNull 속성을 확인하고 수동으로 예외를 throw하는 것이 좋습니다.
CA1872: 'BitConverter.ToString' 기반의 호출 체인보다 'Convert.ToHexString' 및 'Convert.ToHexStringLower'를 선호합니다. 성능 바이트를 16진수 문자열 표현으로 인코딩할 때 Convert.ToHexString 또는 Convert.ToHexStringLower 사용합니다.
CA2022: Stream.Read로 부정확한 읽기 피하기 신뢰도 Stream.Read 호출하면 요청된 바이트보다 적은 바이트를 반환할 수 있으므로 반환 값이 확인되지 않으면 신뢰할 수 없는 코드가 생성됩니다.
CA2262: 'MaxResponseHeadersLength'를 올바르게 설정하십시오 사용법 HttpClientHandler.MaxResponseHeadersLength 속성은 바이트가 아닌 킬로바이트 단위로 측정됩니다.
CA2263: 형식이 알려진 경우 일반 오버로드를 선호합니다. 사용법 제네릭 오버로드는 컴파일 시간에 형식이 알려지면 형식 System.Type 인수를 허용하는 오버로드보다 좋습니다.
CA2264: null을 허용하지 않는 값을 'ArgumentNullException.ThrowIfNull' 전달하지 마세요. 사용법 null을 허용하지 않는 구조체(Nullable<T>제외), 'nameof()' 식 및 'new' 식과 같은 특정 구문은 null이 아닌 것으로 알려져 있으므로 ArgumentNullException.ThrowIfNull throw되지 않습니다.
CA2265: Span<T> null 또는 기본 비교하지 마세요. 사용법 범위를 null 또는 default과 비교해도 원하는 대로 작동하지 않을 수 있습니다. defaultnull 리터럴은 암시적으로 Span<T>.Empty로 변환됩니다. 중복 비교를 제거하거나 IsEmpty사용하여 코드를 보다 명시적으로 만듭니다.