Marginale Neuerungen in .NET 9.0 Release Candidate 1
.NET 9.0 biegt mit dem ersten Release Candidate auf die Zielgerade ein. GegenĂĽber der letzten Preview 7 gibt es nur marginale API-Verbesserungen.
- Dr. Holger Schwichtenberg
Nach sieben Preview-Versionen hat Microsoft .NET 9.0 Release Candidate 1 veröffentlicht. .NET beherrscht die Komprimierung mit zlib und Brotli schon seit Jahren. Mit .NET 9.0 führt Microsoft nun zwei Klassen ZLibCompressionOptions
und BrotliCompressionOptions
ein, mit denen sich spezifische Kompressionseinstellungen vornehmen lassen. Bei der Klasse ZLibCompressionOptions
gibt es die Eigenschaften CompressionStrategy
(eine Enumeration) und CompressionLevel
(eine Ganzzahl 0 bis 9), wobei 0 keine Komprimierung bedeutet. Bei der Klasse BrotliCompressionOptions
gibt es nur eine Eigenschaft Quality
(Ganzzahl 0 bis 11).
Das Listing 1 zeigt ein Einsatzbeispiel, das für alle zehn zlib-Komprimierungslevel sowie für alle zwölf Quality-Level bei der Brotli-Komprimierung die Größe eines komprimierten Textes mit 100.000 Zeichen ausgibt. Abbildung 1 zeigt die Ausgabe des Listings.
// Erzeuge einen Text mit 100000 zufälligen Zeichen
string text = new string(Enumerable.Range(0, 100000).Select(i => (char)(65 + i % 26)).ToArray());
Console.WriteLine("Originaltext: " + text.Length);
for (int i = 0; i <= 9; i++)
{
// Kopiere den Text in einen MemoryStream
var uncompressedStream = new MemoryStream(Encoding.UTF8.GetBytes(text));
var compressedStream = new MemoryStream();
using var zipStream = new ZLibStream(compressedStream, new ZLibCompressionOptions() { CompressionLevel = i, CompressionStrategy = ZLibCompressionStrategy.Default });
uncompressedStream.CopyTo(zipStream);
zipStream.Flush();
Console.WriteLine($"Länge bei ZLib-Komprimierungslevel #{i}: " + compressedStream.Length);
}
for (int i = 0; i <= 11; i++)
{
// Kopiere den Text in einen MemoryStream
var uncompressedStream = new MemoryStream(Encoding.UTF8.GetBytes(text));
var compressedStream = new MemoryStream();
using var brotliStream = new BrotliStream(compressedStream, new BrotliCompressionOptions() { Quality = i });
uncompressedStream.CopyTo(brotliStream);
brotliStream.Flush();
Console.WriteLine($"Länge bei Brotli-Komprimierungslevel #{i}: " + compressedStream.Length);
}
Listing 1: Einsatz der ZLibCompressionOptions und BrotliCompressionOptions
Bei der Klasse TarEntry
bietet .NET 9.0 nun die neue Eigenschaft DataOffset
, die Entwicklerinnen und Entwicklern das Auslesen der Positionen des ersten Bytes eines Eintrags im TAR-Archiv-Stream erlaubt. Das könnte laut Microsoft nützlich sein für Parallelzugriffe auf große TAR-Dateien.
Erweiterte Steuerelemente in MAUI und Blazor
In .NET MAUI 9.0 bietet das Steuerelement Microsoft.Maui.Controls.Label
nun neben den Ausrichtungen linksbĂĽndig (HorizontalTextAlignment="Start"
), rechtsbĂĽndig (HorizontalTextAlignment="End"
) und zentriert (HorizontalTextAlignment="Center"
) endlich auch Blocksatz (HorizontalTextAlignment="Justify"
), siehe Listing 2 und Abbildung 2.
<Label
Text="Lorem ipsum dolor sit amet, consectetur adipiscing elit. In facilisis nulla eu felis fringilla vulputate. Nullam porta eleifend lacinia. Donec at iaculis tellus."
HorizontalTextAlignment="Justify"/>
Listing 2: Blocksatz mithilfe von Microsoft.Maui.Controls.Label
In Blazor können Entwicklerinnen und Entwickler nun beim Steuerelement <InputNumber>
das HTML-Attribut type
setzen, zum Beispiel
<h5>ohne type</h5>
<InputNumber min="1" max="10" step="1" @bind-Value="Zahl" />
<h5>type="range"</h5>
<InputNumber type="range" min="1" max="10" step="1" @bind-Value="Zahl" />
<h5>type="text"</h5>
<InputNumber type="text" min="1" max="10" step="1" @bind-Value="Zahl" />
Verbesserungen bei ASP.NET Core
In .NET 8.0 hatte Microsoft Schlüssel bei der Dependency Injection eingeführt, mit denen Entwicklerinnen und Entwickler mehrere Instanzen einer Klasse im Dependency-Injection-Container mit verschiedenen Schlüsseln registrieren können. In ASP.NET Core 9.0 können nun auch Middleware-Klassen geschlüsselte Dienste im Konstruktor und den Methoden Invoke()
und InvokeAsync()
konsumieren.
Bei WebSockets-Verbindungen lieĂź sich bisher schon per Eigenschaft KeepAliveInterval
(sowohl im Client als auch im Server) festlegen, wie häufig zur Gegenseite eine Ping-Nachricht gesendet werden soll. Es gab aber bisher keine Konsequenz, wenn die Gegenseite nicht antwortete. Nun kann man per KeepAliveTimeout
den Abbruch der Verbindung erzwingen, wenn die Gegenseite nicht innerhalb einer bestimmten Zeit antwortet. Im Server konfiguriert man beispielsweise alle zehn Sekunden eine kurze Nachricht und bricht die Verbindung ab, wenn der Server nicht binnen zwei Sekunden antwortet:
app.UseWebSockets(
new WebSocketOptions {
KeepAliveInterval = TimeSpan.FromSeconds(10),
KeepAliveTimeout = TimeSpan.FromSeconds(2)
});
Im Client sieht die Konfiguration der Eigenschaft KeepAliveTimeout
so aus:
var httpClient = new HttpClient();
var uri = new Uri("wss://server:1234/ws"); // wss: fĂĽr SSL!
var cancellationToken = new CancellationTokenSource().Token;
using var client = new ClientWebSocket();
client.Options.HttpVersionPolicy = HttpVersionPolicy.RequestVersionOrHigher;
client.Options.KeepAliveInterval = TimeSpan.FromSeconds(15);
client.Options.KeepAliveTimeout = TimeSpan.FromSeconds(1); // neu in .NET 9
await client.ConnectAsync(uri, httpClient, cancellationToken);
CUI.Yellow("Verbunden mit WebSockets Server");
Erweiterungen der .NET-SDK-Befehle
Der schon bekannte .NET-SDK-Kommandozeilenbefehl
dotnet dev-certs https --trust
mit dem Entwicklerinnen und Entwickler einem von ASP.NET Core selbst generierten Entwicklungszertifikat vertrauen können, funktioniert nun nicht mehr nur wie bisher auf Windows und macOS, sondern auch unter Ubuntu und Fedora Linux mit Chrome und Firefox.
Der neue .NET-SDK-Befehl
dotnet workload history
zeigt den zeitlichen Ablauf der Veränderungen der SDK-Workload-Installationen auf einem Entwicklungssystem an.
Versteckte Verbesserungen in Entity Framework Core 9.0
Wie schon bei den Vorschauversionen Preview 6 und Preview 7 gibt es keinerlei Release Notes vom Entity-Framework-Core-Entwicklungsteam. Auch das Dokument "What's New in EF Core 9" hat sich seit dem 11. Juni 2024 nicht mehr verändert. Man findet aber auf GitHub 45 geschlossene Issues im Milestone "9.0.0-rc1", darunter folgende Punkte:
- Neben
UseSqlServer()
kann man in der MethodeOnConfiguring()
in der Kontextklasse nun auchUseAzureSql()
oderUseAzureSynapse()
für die Verbindung zu den Cloud-Varianten von SQL Server aufrufen. Microsoft will damit spezielle Features der Cloud-Varianten wie den eigenen Datentyp JSON ausnutzen können. Es ist allerdings nicht dokumentiert, welche Features der Cloud-Varianten Microsoft konkret nutzt. In einem Schnelltest zeigten sich aber fehlende Features:UseNetTopologySuite()
undUseHierarchyId()
kompilieren nicht zusammen mitUseAzureSql()
. - Microsoft hat das von Entity Framework Core 9.0 im Standard angenommene Kompatibilitätslevel für Microsoft SQL Server nach längerer Diskussion auf 150 heruntergesetzt, was einem Microsoft SQL Server 2019 entspricht. In Entity Framework Core 8.0 war das Level 160 (SQL Server 2022). Entwicklerinnen und Entwickler sollten das Kompatibilitätslevel explizit mit
UseCompatibilityLevel()
setzen, wenn sie mit anderen SQL-Server-Versionen als dem Standard arbeiten. - Microsoft unterstĂĽtzt seit Entity Framework Core 8.0 Mengen von primitiven Typen (etwa
int[]
,List<Guid>
), aber nicht das Mapping verschachtelter Mengen, etwaint[][]
. Das bleibt auch in Entity Framework Core 9.0 so, die Fehlermeldung ist nun aber konkreter: "int[][] is a primitive collection of a primitive collection. Nested primitive collections are not yet supported with relational database providers.". Zuvor hieĂź es nur allgemeiner: "is not a supported primitive type or a valid entity type".
Installation
.NET 9.0 Release Candidate 1 installiert man im Rahmen von Visual Studio 2022 Version 17.12 Preview 2 oder eigenständig mit dem Setup-Paket von der Website. Einige neue Einträge gibt es in der Liste der Breaking Changes in .NET 9.0 gegenüber .NET 8.0.
Ausblick
Microsoft hat den 12. November 2024 als Erscheinungstermin für .NET 9.0 offiziell bekannt gegeben. Bis dahin wird es im Oktober noch den Release Candidate 2 geben. Die stabile Version präsentieren Heise, iX und der dpunkt.verlag zusammen mit www.IT-Visions.de bei dem Online-Event betterCode() .NET 9.0 eine Woche später, am 19. November 2024.
(mai)