One .NET ist auf dem Weg

Ausblick auf .NET 6
20
Jul

One .NET ist auf dem Weg

Mit .NET 6 kommt nicht nur die ursprünglich schon für .NET 5 geplante Vereinheitlichung „One .NET“, sondern es wird auch neue Anwendungsarten und weitere Verbesserungen für die Entwickler geben.

Der Nachfolger von .NET 5.0 soll im November dieses Jahres erscheinen und – wie in der Einleitung schon geschrieben – offiziell nur noch „.NET 6“, also ohne „.0“, heißen, wie aus einem Blogeintrag des Program Manager Richard Lander hervorgeht [1]. Microsoft hält sich aber selbst noch nicht daran, wie man auf der .NET-6-Downloadseite [2] in Abbildung 1 unschwer sieht. Zum Zeitpunkt der Erstellung dieses Beitrags sind dort Preview 1 und 2 verfügbar. Bis zur Auslieferung dieses Heftes wird es aber eine oder zwei weitere Previews geben. Wie bisher gibt es drei Runtimes (Konsole, Desktop und ASP.NET Core) sowie ein monolithisches SDK. Von der geplanten Modularisierung des SDK sieht man erste Ansätze, wenn aufgefordert wird, Workloads für Android und iOS nachzuinstallieren [3]. Bis zum fertigen Release soll man die Workloads direkt über den .NET-SDK-Befehl dotnet install beziehen können.

Neu bei den Runtimes für Konsole und ASP.NET Core ist die Unterstützung für den neuen ARM-64-basierten Apple-Chip M1 alias Apple Silicon. Während Microsoft in den Blogeinträgen [4] und [5] immer nur von Apple Silicon spricht, erscheint die neue Runtime in der Liste der Downloads unter macOS/Arm64.

 

Abb. 1: Übersicht über SDK und Runtimes in .NET 6 Preview 2 [2]

 

Wie bisher laufen Windows Forms und WPF nur auf Windows. Daran wird sich auch in .NET 6 nichts ändern. Das gilt auch für die kommende Windows UI Library 3 (WinUI 3), dem designierten Nachfolger von UWP und WPF. Microsoft geht in .NET 6 das Thema Cross-Platform (Abb. 2) aus zwei Richtungen an:

 

  1. Das .NET Multi-Platform App UI (MAUI) ist der Nachfolger von Xamarin.Forms und wird auf Android, iOS, Windows und macOS laufen. Linux ist vorerst ausgeklammert, aber in Diskussion [6]. Das UI wird hier weiterhin durch XAML beschrieben.
  2. Blazor Desktop wird eine hybride Lösung sein: HTML UI verpackt in eine Desktopanwendung (vgl. den Ansatz von GitHubs Electron).

 

Abb. 2: Aufbau .NET 6

 

MAUI

Microsoft hatte auf der Build-Konferenz im Mai 2020 angekündigt, das im Jahr 2016 zugekaufte Produkt Xamarin ganz in die aktuelle .NET-Welt zu integrieren. So soll die App-Entwicklung zukünftig die gleichen Werkzeuge aus dem .NET 6 SDK sowie die gleiche Klassenbibliothek wie der Rest von .NET 6 verwenden (Abb. 2). Im Hintergrund wirkt freilich in einigen Anwendungsarten weiterhin eine auf Mono basierende Runtime, wovon der Entwickler aber gar nichts mehr merken soll. Die Integration wird von Umbenennungen begleitet: Aus Xamarin.iOS wird „.NET for iOS“, aus Xamarin.Android „.NET for Android“ und aus Xamarin.Forms wird „.NET Multi-Platform App UI“ (MAUI). Zusammenfassend spricht Microsoft von .NET 6 Mobile [3]. Entsprechend gibt es nun neue Target Frameworks: net6.0-ios und net6.0-android. Seit .NET 6 Preview 2 können App-Entwickler nun erste einfache .NET-6-Mobile-Projekte für Android, iOS und Mac Catalyst auf Basis des .NET 6 SDK erstellen. Auf GitHub [3] sind Beispiele zu sehen.

Während bisher in Xamarin neben dem Shared Code für jede Zielplattform ein sogenanntes Kopfprojekt notwendig war, kann der App-Entwickler nun aus einem einzigen Projekt heraus unmittelbar für verschiedene Plattformen kompilieren („single, multi-targeted application project“). Ein MAUI-Projekt referenziert das Paket Microsoft.Maui und listet die gewünschten Target Frameworks auf, z. B. net6.0-android;net6.0-ios;net6.0-windows. Im Projekt sind plattformspezifisches XAML, plattformspezifischer Programmcode und plattformspezifische Ressourcen möglich (Abb. 3). Zum Übersetzen verwendet man derzeit noch die Kommandozeile, z. B. dotnet build HelloMaui -t:Run -f net6.0-android.

 

Abb. 3: Hello World in MAUI

 

Blazor 6

Das Entwicklungsteam für Blazor hat in .NET 6 Preview 2 bereits erhebliche Geschwindigkeitsvorteile im Entwicklungsprozess umgesetzt. Im Vergleich zu .NET 5.0 sind sowohl ein erster als auch ein inkrementeller Übersetzungsvorgang deutlich schneller [7], wie Abbildung 4 zeigt. Dort ist ebenfalls zu sehen, dass davon auch ASP.NET MVC profitiert. Ein Teil des Geschwindigkeitsvorteils basiert auf einem Compiler für ASP.NET-Core-Razor-Templates; dieser verwendet die in C# 9.0 eingeführten Source Code Generators.

 

Abb. 4: Geschwindigkeitssteigerungen beim Kompilieren von Razor Templates in Blazor und MVC in .NET 6 Preview 2 [7]

 

Geplant ist, für alle ASP.NET-Core-Anwendungsarten ein Hot Reloading/Hot Restart sowie Edit and Continue (EnC) beim Debugging bereitzustellen. Microsoft spricht von der „Inner Loop Performance“. Die Liste der dazu geplanten Verbesserungen findet man auf GitHub [8]. Auch zur Laufzeit soll es gerade bei Blazor WebAssembly schneller und schlanker zugehen. Ursprünglich stand im Plan, eine „Hello World“-Anwendung auf eine Größe von 0,5 MB zu drücken [9]. Dieses wohl doch zu hohe Ziel wurde aber inzwischen herauseditiert und durch die Aussage ersetzt, man wolle die bestehende Größe von 2.2 MB um mindestens 20 Prozent reduzieren. In Preview 1 gab es für Blazor die neue Razor Component <DynamicComponent>. Mit ihr kann man eine beliebige andere Komponente dynamisch rendern. Die Blazor-Eingabesteuerelemente haben nun einen direkten Zugang zur Element Reference, die der Entwickler zum Zugriff per JavaScript braucht. Seit Preview 2 gibt es mehr Flexibilität für die Parameterübergabe bei der Ereignisbehandlung. Bei generischen Komponenten muss der Entwickler nun in weiteren Fällen keine Typparameter mehr explizit angeben, weil die Blazor-Laufzeitumgebung den Typ automatisch ableiten kann. Beim Einsatz von Server-Prerendering mit dem neuen Tag-Helper <preserve-component-state /> kann der Entwickler in .NET 6 eine Zustandsverwaltung aktivieren, die eine erneute Verarbeitung in der Hauptrenderphase vermeidet.

In .NET 6 sollen erstmals auch hybride Blazor-Anwendungen als fertige Version unter dem Titel „Blazor Desktop“ erscheinen. Das ist seit längerem in Arbeit [10]. Blazor Desktop soll auf dem .NET Multi-Platform App UI (MAUI), dem Nachfolger von Xamarin.Forms, basieren und dort in einem WebView2-Steuerelement die von einer Blazor-Anwendung generierten HTML-Oberflächen darstellen. Da MAUI zunächst bei den Desktopbetriebssystemen nur Windows und macOS unterstützt, findet man Linux nicht in Abbildung 5. Android und iOS werden zwar von MAUI unterstützt, sind aber zunächst nicht von Blazor Desktop abgedeckt. Es soll aber möglich sein, im Rahmen der Blazor Mobile Bindings auch HTML-Inhalte von Blazor darzustellen.

 

Abb. 5: Pläne für Blazor Desktop; Quelle: Microsoft .NET Conf – Focus on Windows (25.02.2021)

 

Für alle ASP.NET-Core-basierten Anwendungsarten hat Microsoft begonnen, die ASP.NET-Core-Klassen für die bessere Unterstützung der in C# 8.0 eingeführten Nullable Reference Types zu annotieren.

Die in Blazor 5.0 eingeführte CSS-Isolation (Beschränkung der Gültigkeit auf einzelne .razor-Komponenten) funktioniert in .NET 6 auch mit den älteren Multi-Page-Programmiermodellen Model View Controller (MVC) und Razor Pages. IAsyncDisposable funktioniert nun für Controller, Page Models und View Components.

 

Entity Framework Core 6

Entity Framework Core 6.0 soll im November 2021 zusammen mit .NET 6 erschienen. Der OR-Mapper bietet seit .NET 6 Preview 1 neue Annotationen wie [Unicode], [Precision] und [EntityTypeConfiguration]. Der Datenbanktreiber für SQLite unterstützt nun ToString() und das in Version 5.0 eingeführte Savepoints API. Für den Microsoft SQL Server kann man nun per Fluent API eine Spalte als „Sparse Column“ deklarieren und damit Speicherplatz in den Datenbankdateien einsparen – für den Fall, dass viele Nullwerte vorkommen, was beim Table-per-Hierarchy-Mapping häufig auftritt, da hier eine ganze Vererbungshierarchie in einer Tabelle lebt. Auch die Methode IsNullOrWhitespace() unterstützt der SQL-Server-Treiber nun. Für SQL Server, SQLite und Cosmos DB funktioniert die Zufallszahlengenerierung mit EF.Functions.Random(). Beim Reverse Engineering übernimmt der Befehl Scaffold-DbContext jetzt Kommentare zu Tabellen und Spalten aus dem Datenmodell in den generierten Programmcode.

Preview 2 bietet hingegen nur kleine Verbesserungen: String.Concat() funktioniert auch mit mehr als zwei Parametern. SqlServerDbFunctionsExtensions.FreeText() und SqlServerDbFunctionsExtensions.Contains() funktionieren jetzt auch mit binären Spalten und in Zusammenarbeit mit Value-Konvertern. Außerdem hat Microsoft ein schon länger bestehendes lästiges Problem [11] mit doppelten Typen in zwei verschiedenen Assemblies in Zusammenhang mit asynchronen LINQ-Operationen endlich gelöst [12].

Weitere Pläne für Entity Framework Core 6.0 hat Microsoft am 18.1.2021 veröffentlicht [13]. Dazu gehören:

 

  • N:M-Unterstützung beim Reverse Engineering
  • Mapping für Spalten mit Typ JSON
  • Unterstützung für temporale Tabellen im Microsoft SQL Server
  • Festlegung der Reihenfolge beim Anlegen von Spalten (Order)
  • Migration Bundles für Schemamigrationen (war schon für Version 5.0 geplant: Alternativ zu einem SQL-Skript soll eine ausführbare Datei generiert werden, die das Datenbankschema aktualisiert)
  • Leistungsverbesserungen, insbesondere schnellerer Start durch kompilierte Modelle
  • Unterstützung für ADO.NET Batching API [14]

 

Bei der Performance hat sich Microsoft vorgenommen, im TechEmpower Benchmark [15] den konkurrierenden Micro-ORM Dapper von StackExchange [16] zu schlagen.

 

Weitere Verbesserungen in Preview 1 und 2

Das in .NET Core 3.0 eingeführte und bisher in C++ geschriebene CrossGen-Werkzeug wurde in C# neu implementiert (CrossGen2). Diese Version erlaubt eine profilgesteuerte Optimierung (PGO). Seit Preview 2 kompiliert Microsoft mit CrossGen2 alle Microsoft.NETCore.App Assemblies im .NET SDK zu Maschinencode vor. Weitere Anwendungsarten wie Windows Desktop sind für Preview 3 und 4 geplant. Bei den Basisklassen gibt es mit der Klasse System.Collections.Generic.PriorityQueue<TElement, TPriority> nun eine neue Warteschlange mit Priorität; bei der Entnahme werden die Werte nicht anhand der Einfügereihenfolge, sondern auf Basis der bei der Hineingabe angegebenen Priorität entnommen. Auch bei den mathematischen APIs im Namensraum System.Numerics gibt es Erweiterungen. Selbst bei den Basisfunktionen ToString() und TryFormat() hat Microsoft nach 20 Jahren .NET noch Verbesserungspotenzial erkannt und realisiert, vgl. Beispiele im Blogeintrag [5].

Der von Microsoft bereits in .NET Core 3.0 neu implementierte JSON Serializer System.Text.Json kann nun endlich auch – wie sein Vorgänger JSON.NET – Schleifen in Objektbäumen ignorieren. Die Komponente System.Threading.AccessControl bietet Verbesserungen für Access Control Lists auf Windows.
 

Ausblick

Es steht noch Einiges auf der Agenda für .NET 6 (vgl. www.themesof.net), was man nicht in Preview 1 und 2 sieht, u. a.:

 

  • C# 10
  • Ahead-of-Time-Kompilierung als Alternative zum Just-In-Time-Compiler
  • Single-File-Apps für alle Anwendungsarten inkl. Debugging
  • Verbessertes Application Trimming (Tree Shaking)
  • HTTP/3 auf Basis von Quick UDP Internet Connections (QUIC)
  • Client-Retry für gRPC
  • Anpassbarer Reverse Proxy
  • Leichterer Einstieg für neue Entwickler

 

Fazit

Ich persönlich freue mich in .NET 6 am meisten auf die Beschleunigung des Entwicklungsprozesses durch die Optimierung beim Kompilieren und Debugging, denn ich hasse es, bei der täglichen Programmierarbeit an Kundenprojekten immer einige Sekunden warten zu müssen, bis ich das Ergebnis meiner jüngsten Änderungen live sehe.

 

Links & Literatur

[1] https://devblogs.microsoft.com/dotnet/announcing-net-6-preview-1/

[2] https://dotnet.microsoft.com/download/dotnet/6.0

[3] https://github.com/dotnet/net6-mobile-samples

[4] https://devblogs.microsoft.com/dotnet/announcing-net-6-preview-1/

[5] https://devblogs.microsoft.com/dotnet/announcing-net-6-preview-2/

[6] https://github.com/jsuarezruiz/forms-gtk-progress/issues/31

[7] https://devblogs.microsoft.com/aspnet/asp-net-core-updates-in-net-6-preview-2

[8] https://github.com/dotnet/core/issues/5510

[9] https://github.com/dotnet/runtime/issues/44317

[10] https://github.com/aspnet/AspLabs/tree/main/src/ComponentsElectron

[11] https://github.com/dotnet/efcore/issues/18124

[12] https://github.com/dotnet/efcore/issues/24041

[13] https://devblogs.microsoft.com/dotnet/the-plan-for-entity-framework-core-6-0/

[14] https://github.com/dotnet/runtime/issues/28633

[15] https://www.techempower.com/benchmarks/#section=data-r19&hw=ph&test=db

[16] https://github.com/StackExchange/Dapper

Ihr aktueller Zugang zur .NET- und Microsoft-Welt.
Der BASTA! Newsletter:

Behind the Tracks

.NET Framework & C#
Visual Studio, TFS, C# & mehr

Agile & DevOps
Best Practices & mehr

Web Development
Alle Wege führen ins Web

Data Access & Storage
Alles rund um´s Thema Data

HTML5 & JavaScript
Leichtegewichtig entwickeln

User Interface
Alles rund um UI- und UX-Aspekte

Microservices & APIs
Services, die sich über APIs via REST und JavaScript nutzen lassen

Security
Tools und Methoden für sicherere Applikationen

Cloud & Azure
Cloud-basierte & Native Apps