Freigeben über


Neuerungen im SDK und tooling für .NET 9

In diesem Artikel werden neue Features im .NET SDK und tools für .NET 9 beschrieben.

Komponententests

In diesem Abschnitt werden die Updates für Komponententests in .NET 9 beschrieben: Ausführen von Tests parallel und Terminal Logger-Testausgabe.

Parallele Ausführung von Tests

In .NET 9 dotnet test ist er vollständig in MSBuild integriert. Da MSBuild das Erstellen parallel unterstützt, können Sie Tests für dasselbe Projekt in verschiedenen Zielframeworks parallel ausführen. Standardmäßig schränkt MSBuild die Anzahl paralleler Prozesse auf die Anzahl der Prozessoren auf dem Computer ein. Sie können auch ihren eigenen Grenzwert mit dem Switch "-maxcpucount " festlegen. Wenn Sie die Parallelität deaktivieren möchten, legen Sie die TestTfmsInParallel MSBuild-Eigenschaft auf false.

Terminal Logger-Testanzeige

Die Berichterstattung von Testergebnissen für dotnet test wird jetzt direkt im MSBuild Terminal Logger unterstützt. Sie erhalten detailliertere Testberichte sowohl während der Ausführung von Tests (zeigt den Namen des ausgeführten Tests) als auch nach dem Abschluss der Tests, wobei alle Testfehler auf ansprechendere Weise dargestellt werden.

Weitere Informationen zu Terminal Logger finden Sie unter dotnet build options.

.NET-Tool Fortschreibungsmechanismus

.NET-Tools sind frameworkabhängige Apps, die Sie global oder lokal installieren können, und führen Sie dann mit dem .NET SDK und installierten .NET-Runtimes aus. Diese Tools, wie alle .NET-Apps, richten sich an eine bestimmte Hauptversion von .NET. Apps werden standardmäßig nicht für neuere Versionen von .NET ausgeführt. Toolautoren konnten sich dafür entscheiden, ihre Tools auf neueren Versionen der .NET-Laufzeit auszuführen, indem sie die RollForward MSBuild-Eigenschaft festlegen. Allerdings tun nicht alle Tools dies.

Mit einer neuen Option dotnet tool install können Benutzer entscheiden, wie .NET-Tools ausgeführt werden sollen. Wenn Sie ein Tool über dotnet tool install installieren oder das Tool über dotnet tool run <toolname> ausführen, können Sie ein neues Flag angeben, das --allow-roll-forward genannt wird. Mit dieser Option wird das Tool im Roll-Forward-Modus Majorkonfiguriert. Mit diesem Modus kann das Tool auf einer neueren Hauptversion von .NET ausgeführt werden, wenn die entsprechende .NET-Version nicht verfügbar ist. Dieses Feature hilft Early Adopters bei der Verwendung von .NET-Tools, ohne dass Autoren von Tools Code ändern müssen.

Terminal-Protokollierer

Terminal Logger ist jetzt standardmäßig aktiviert und hat auch die Benutzerfreundlichkeit verbessert.

Standardmäßig aktiviert

Ab .NET 9 ist die Standardoberfläche für alle .NET CLI-Befehle, die MSBuild verwenden, terminal Logger, die erweiterte Protokollierungsoberfläche, die in .NET 8 veröffentlicht wurde. Diese neue Ausgabe verwendet die Funktionen moderner Terminals, um Funktionen wie:

  • Klickbare Links
  • Dauerzeitgeber für MSBuild-Aufgaben
  • Farbcodierung von Warnmeldungen und Fehlermeldungen

Die Ausgabe ist komprimierter und verwendbarer als der vorhandene MSBuild-Konsolenprotokollierer.

Der neue Logger versucht, automatisch zu erkennen, ob er verwendet werden kann, aber Sie können auch manuell steuern, ob Terminal logger verwendet wird. Geben Sie die --tl:off Befehlszeilenoption an, um terminal logger für einen bestimmten Befehl zu deaktivieren. Um den Terminal Logger im Allgemeinen zu deaktivieren, setzen Sie die MSBUILDTERMINALLOGGER-Umgebungsvariable auf off.

Der Satz von Befehlen, die terminal logger standardmäßig verwenden, lautet:

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

Usability

Terminal Logger fasst nun die Gesamtanzahl der Fehler und Warnungen am Ende eines Builds zusammen. Außerdem werden Fehler angezeigt, die Neueinleitungen enthalten. (Weitere Informationen zu Terminal Logger finden Sie unter "dotnet build"-Optionen, insbesondere in der --tl Option.)

Berücksichtigen Sie die folgende Projektdatei, die beim Erstellen des Projekts eine Warnung ausgibt:

<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>

Wenn Sie dotnet build -tl auf dem .NET 8 SDK ausführen, wird die Ausgabe wie im folgenden Absatz angezeigt. Jede Zeile der mehrzeiligen Warnung ist eine separate Zeile mit einem vollständigen Fehlermeldungspräfix in der Ausgabe, die schwer zu lesen ist. Außerdem gibt die endgültige Buildzusammenfassung an, dass Warnungen vorhanden waren , aber nicht , wie viele es gab. Die fehlenden Informationen können es schwierig machen zu ermitteln, ob ein bestimmter Build besser oder schlechter als vorherige Builds ist.

$ 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

Wenn Sie dasselbe Projekt mit dem .NET 9 SDK erstellen, lautet die Ausgabe wie folgt:

> 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

Die Meldungszeilen der Warnung enthalten nicht mehr die wiederholten Projekt- und Standortinformationen, die die Anzeige überladen. Darüber hinaus zeigt die Buildzusammenfassung, wie viele Warnungen (und Fehler, falls vorhanden) während des Builds generiert wurden.

Wenn Sie Feedback zu Terminal Logger haben, können Sie es im MSBuild-Repository bereitstellen.

Schnellere NuGet-Abhängigkeitsauflösung für große Repositorys

Der NuGet-Abhängigkeitslöser wurde überarbeitet, um die Leistung und Skalierbarkeit für alle <PackageReference> Projekte zu verbessern. Standardmäßig aktiviert, beschleunigt der neue Algorithmus Wiederherstellungsvorgänge, ohne die Funktionalität zu beeinträchtigen, wobei die Kernabhängigkeitsauflösungsregeln strikt eingehalten werden.

Wenn Probleme auftreten, z. B. Wiederherstellungsfehler oder unerwartete Paketversionen, können Sie zum älteren Resolver zurückkehren.

MSBuild-Skriptanalyses ("BuildChecks")

.NET 9 führt ein Feature ein, mit dem Fehler und Regressionen in Ihren Buildskripts geschützt werden können. Um die Buildprüfungen auszuführen, fügen Sie das /check Flag zu einem beliebigen Befehl hinzu, der MSBuild aufruft. Erstellt beispielsweise dotnet build myapp.sln /check die myapp Lösung und führt alle konfigurierten Buildprüfungen aus.

Das .NET 9 SDK enthält eine kleine Anzahl von anfänglichen Prüfungen, z. B. BC0101 und BC0102. Eine vollständige Liste finden Sie unter BuildCheck-Codes.

Wenn ein Problem erkannt wird, wird eine Diagnose in der Buildausgabe für das Projekt erstellt, das das Problem enthält.

Weitere Informationen finden Sie in der Entwurfsdokumentation.

Analysator-Unstimmigkeit

Viele Benutzer installieren das .NET SDK und Visual Studio in unterschiedlichen Takten. Obwohl diese Flexibilität wünschenswert ist, kann es zu Problemen für Werkzeuge führen, die zwischen den beiden Umgebungen interoperieren müssen. Ein Beispiel für diese Art von Werkzeug ist Roslyn Analyzers. Analyseautoren müssen für spezifische Roslyn-Versionen codieren, aber welche Versionen verfügbar sind und welche von einem jeweiligen Build verwendet werden, ist manchmal unklar.

Diese Art von Versionskonflikt zwischen .NET SDK und MSBuild wird als torn SDK bezeichnet. Wenn Sie sich in diesem Zustand befinden, werden möglicherweise Fehler wie folgt angezeigt:

CSC: Warnung CS9057: Die Analyzerassembly '..\dotnet\sdk\8.0.200\Sdks\Microsoft.NET.Sdk.Razor\source-generators\Microsoft.CodeAnalysis.Razor.Compiler.SourceGenerators.dll' verweist auf Version '4.9.0.0' des Compilers, der neuer als die derzeit ausgeführte Version "4.8.0.0".

.NET 9 kann dieses Problemszenario erkennen und automatisch anpassen. Die MSBuild-Logik des SDK bettet die version von MSBuild ein, mit der sie ausgeliefert wurde, und diese Informationen können verwendet werden, um zu erkennen, wann das SDK in einer Umgebung mit einer anderen Version ausgeführt wird. In diesem Fall fügt das SDK einen impliziten Download eines Supportpakets mit dem Namen Microsoft.Net.Sdk.Compilers.Toolset ein, das eine konsistente Analyseumgebung gewährleistet.

Workloadsätze

Workload-Sätze sind ein SDK-Feature, mit dem Benutzer mehr Kontrolle über die von ihnen installierten Workloads und die Häufigkeit der Änderung dieser Workloads erhalten. In früheren Versionen wurden Workloads regelmäßig aktualisiert, da neue Versionen einzelner Workloads für alle konfigurierten NuGet-Feeds freigegeben wurden. Jetzt bleiben alle Ihre Workloads auf einer bestimmten, einzelnen Version, bis Sie eine explizite Aktualisierung vornehmen.

Sie können sehen, in welchem Modus sich die SDK-Installation befindet, indem Sie Folgendes ausführen dotnet workload --info:

> 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

In diesem Beispiel befindet sich die SDK-Installation im Manifestmodus, in dem Updates installiert werden, sobald sie verfügbar sind. Um sich für den neuen Modus zu entscheiden, fügen Sie eine dotnet workload update Option einem --version oder dotnet workload install Befehl hinzu. Sie können den Modus des Vorgangs auch explizit mit dem neuen dotnet workload config Befehl steuern:

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

Wenn Sie aus irgendeinem Grund zurückwechseln müssen, können Sie denselben Befehl mit manifests anstelle von workload-set ausführen. Sie können auch den aktuellen Betriebsmodus mit dotnet workload config --update-mode überprüfen.

Weitere Informationen finden Sie unter .NET SDK-Workloadsätze.

Workloadverlauf

.NET SDK-Workloads sind ein integraler Bestandteil von .NET MAUI und Blazor WebAssembly. In ihrer Standardkonfiguration können Sie Workloads unabhängig aktualisieren, da .NET-Toolautoren neue Versionen veröffentlichen. Darüber hinaus installieren .NET SDK-Installationen, die über Visual Studio durchgeführt werden, einen parallelen Satz von Versionen. Ohne Sorgfalt kann der Installationsstatus einer bestimmten .NET SDK-Workload im Laufe der Zeit abweichen, aber es gab keine Möglichkeit, diese Abweichung zu visualisieren.

Um dies zu beheben, fügt .NET 9 dem .NET SDK einen neuen dotnet workload history Befehl hinzu. dotnet workload history druckt eine Tabelle des Verlaufs von Workloadinstallationen und Änderungen für die aktuelle .NET SDK-Installation aus. In der Tabelle wird das Datum der Installation oder Änderung, der ausgeführte Befehl, die installierten oder geänderten Workloads und die relevanten Versionen für den Befehl angezeigt. Diese Ausgabe kann Ihnen helfen, die Abweichung von Workload-Installationen im Laufe der Zeit nachvollziehen zu können und fundierte Entscheidungen darüber zu treffen, auf welche Workload-Versionen Sie Ihre Installation umstellen sollten. Sie können sich dies wie git reflog für Workloads vorstellen.

> 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

In diesem Beispiel wurde das SDK zunächst mit den android, ios, , maccatalystund maui-windows Workloads installiert. Anschließend wurde der dotnet workload install aspire --version 9.0.100-rc.1.24453.3 Befehl verwendet, um die aspire Workloads zu installieren und in den Modus für Workload-Sets zu wechseln. Um zum vorherigen Zustand zurückzukehren, können Sie die ID aus der ersten Spalte in der Verlaufstabelle verwenden, dotnet workload update --from-history 1z. B. .

Behälter

Veröffentlichungsunterstützung für unsichere Registrierungen

Die integrierte Unterstützung für die Veröffentlichung von Containern im SDK kann Images in Container-Registries veröffentlichen. Bis .NET 9 mussten diese Registrierungen gesichert werden– damit das .NET SDK funktioniert, benötigten sie HTTPS-Unterstützung und gültige Zertifikate. Containermodule können in der Regel so konfiguriert werden, dass sie auch mit unsicheren Registrierungen funktionieren, d. h. Registrierungen, die tls nicht konfiguriert haben, oder TLS mit einem ungültigen Zertifikat konfiguriert haben. Dies ist ein gültiger Anwendungsfall, aber unser Tool hat diesen Kommunikationsmodus nicht unterstützt.

Ab .NET 9 kann das SDK mit unsicheren Registrierungen kommunizieren.

Anforderungen (abhängig von Ihrer Umgebung):

  • Konfigurieren Sie die Docker CLI, um eine Registrierung als unsicher zu kennzeichnen.
  • Konfigurieren Sie Podman, um eine Registrierung als unsicher zu kennzeichnen.
  • Verwenden Sie die DOTNET_CONTAINER_INSECURE_REGISTRIES Umgebungsvariable, um eine durch Semikolons getrennte Liste von Registrierungsdomänen zu übergeben, die als unsicher behandelt werden sollen.

Benennung von Umgebungsvariablen

Umgebungsvariablen, die das Tool zum Veröffentlichen von Containern verwendet, um einige der feineren Aspekte der Registrierungskommunikation und -sicherheit zu steuern, beginnen jetzt mit dem Präfix DOTNET anstelle von SDK. Das SDK Präfix wird in Kürze weiterhin unterstützt.

Codeanalyse

.NET 9 enthält mehrere neue Codeanalysatoren und Fixer, um sicherzustellen, dass Sie .NET-Bibliotheks-APIs ordnungsgemäß und effizient verwenden. In der folgenden Tabelle sind die neuen Analysegeräte zusammengefasst.

Regel-ID Kategorie Description
CA1514: Vermeiden sie redundantes Längenargument Wartbarkeit Ein explizit berechnetes Längenargument kann fehleranfällig sein und ist nicht erforderlich, wenn Sie bis zum Ende eines Strings oder eines Puffers schneiden.
CA1515: Erwägen Sie, öffentliche Typen als intern festzulegen Wartbarkeit Typen innerhalb einer ausführbaren Assembly sollten als internaldeklariert werden.
CA1871: Übergeben Sie keine nullable Struktur an 'ArgumentNullException.ThrowIfNull' Leistung Um die Leistung zu verbessern, ist es besser, die HasValue-Eigenschaft zu überprüfen und manuell eine Ausnahme auszuwerfen, als eine nullable Struktur an ArgumentNullException.ThrowIfNull zu übergeben.
CA1872: Bevorzugen Sie 'Convert.ToHexString' und 'Convert.ToHexStringLower' anstelle von Aufrufketten basierend auf 'BitConverter.ToString' Leistung Verwenden Sie Convert.ToHexString oder Convert.ToHexStringLower, wenn Bytes in eine hexadezimale Zeichenfolgendarstellung kodiert werden.
CA2022: Ungenaue Lesevorgänge mit Stream.Read vermeiden Zuverlässigkeit Ein Aufruf von Stream.Read könnte weniger Bytes zurückgeben, als angefordert wurden, was zu unzuverlässigem Code führt, wenn der Rückgabewert nicht überprüft wird.
CA2262: "MaxResponseHeadersLength" richtig festlegen Usage Die HttpClientHandler.MaxResponseHeadersLength Eigenschaft wird in Kilobyte gemessen, nicht in Byte.
CA2263: Generische Überladung bevorzugen, wenn der Typ bekannt ist Usage Generische Überladungen sind gegenüber Überladungen vorzuziehen, die ein Argument vom Typ System.Type akzeptieren, wenn der Typ zur Kompilierungszeit bekannt ist.
CA2264: Übergeben Sie keinen nicht nullfähigen Wert an 'ArgumentNullException.ThrowIfNull' Usage Bestimmte Konstrukte wie nicht-nullbare Strukturen (mit Ausnahme von Nullable<T>), "nameof()"-Ausdrücke und "new"-Ausdrücke sind dafür bekannt, niemals null zu sein, sodass ArgumentNullException.ThrowIfNull niemals ausgelöst wird.
CA2265: Vergleichen Sie nicht Span<T> mit Null oder Standard Usage Vergleichen Sie eine Spanne mit null oder default, macht es möglicherweise nicht das, was Sie beabsichtigt haben. default und das null Literal werden implizit in Span<T>.Empty umgewandelt. Entfernen Sie den redundanten Vergleich, oder gestalten Sie den Code klarer, indem Sie IsEmpty verwenden.