Umstieg auf .NET Core, Teil 1: Migrieren oder nicht migrieren?

Microsoft entwickelt das .NET Framework nicht mehr weiter. Vor dem Umstieg auf .NET Core stellt sich daher die Frage, ob man migrieren muss oder sollte.

In Pocket speichern vorlesen Druckansicht 64 Kommentare lesen
Umstieg auf .NET Core – Migrieren oder nicht migrieren?

(Bild: Matthias Parbel)

Lesezeit: 13 Min.
Von
  • Dr. Holger Schwichtenberg
Inhaltsverzeichnis

Das klassische .NET Framework hat Microsoft in den letzten drei Jahren nur noch in sehr kleinen Schritten (4.6.2, 4.7, 4.7.1, 4.7.2, 4.8) weiterentwickelt. Die aktuelle Version 4.8 stammt aus dem April 2019. Im Mai folgte dann die Ankündigung, dass Version 4.8 das letzte Release des .NET Framework bleiben werde. Microsoft will künftig nur noch mit kleineren Updates Probleme im Bereich Zuverlässigkeit und Sicherheit sowie kritische funktionale Fehler beheben.

Umstieg auf .NET Core

In dieser fünfteiligen Artikelserie geht Holger Schwichtenberg der grundsätzlichen Frage nach, ob Organisationen, die zum Teil schon seit Anfang der 2000er Jahre mit dem klassischen .NET Framework entwickeln, ihren bestehenden Programmcode nun auf .NET Core umstellen sollten. Ist die Entscheidung für eine Migration gefallen, dann gilt es, eine Reihe von Herausforderungen zu meistern:

Das neu gestaltete .NET Core hat sich in der gleichen Zeit sehr agil entwickelt: Von .NET Core 1.0 im Juli 2016 über die Versionen 1.1, 2.0, 2.1, 2.2 bis zur Version 3.0 im September 2019 (siehe Abbildung 1) – .NET Core 3.1 folgte im Dezember 2019. Als gemeinsamen Nachfolger von .NET Core, .NET Framework und Mono/Xamarin stellt Microsoft für November 2020 .NET 5.0 (ohne Core im Namen) in Aussicht. Technisch gesehen basiert .NET 5.0 auf .NET Core; .NET Framework und Mono/Xamarin fließen nur partiell ein.

Entwicklung der APIs in .NET Core im Vergleich zu .NET Framework 4.8 (Abb.1).

(Bild: Microsoft GitHub .NET)

Viele Organisationen, die zum Teil schon seit Anfang der 2000er Jahren mit dem klassischen .NET Framework entwickeln, stellen sich nun die Frage, ob sie den bestehenden Programmcode (oft viele Hunderttausend, manchmal sogar Millionen Zeilen Code) nun auf .NET Core umstellen müssen.

Einen zwingenden technischen oder rechtlichen Grund gibt es nicht – so viel sei vorweg gesagt. Microsoft erlaubt weiterhin, das .NET Framework in der Softwareentwicklung aktiv zu verwenden, und zwar auf unbestimmte Zeit. Microsofts zentrale Zusicherungen zu diesem Thema lauten:

Die drei Aussagen stammen von Scott Hunter, Director Program Management für .NET. Natürlich hat Microsoft in seiner Firmengeschichte auch immer wieder einmal die Meinung geändert und Aussagen revidiert oder zurückgenommen. Aber die Tatsache, dass Microsoft selbst einige Produkte auf .NET-Basis besitzt (nicht nur Teile von Windows, sondern auch SharePoint, Microsoft Office und SQL Server verwenden .NET Framework), nährt die Hoffnung, dass diese Aussagen lange Bestand haben werden. Schließlich laufen DOS-Anwendungen und Visual-Basic-6.0-Anwendungen auch heute noch in einem aktuellen Windows 10.

Wer bei .NET Framework verbleibt, begibt sich allerdings auf ein Abstellgleis. Microsoft wird nur noch .NET Core (beziehungsweise .NET 5, .NET 6, .NET 7 usw.) aktiv weiterentwickeln. Hin und wieder wird vielleicht ein Nuget-Paket veröffentlicht, das auch auf dem klassischen .NET Framework läuft – wie im Fall der neuen JSON-Bibliothek. Aber es wird auch immer mehr Bibliotheken geben, die nur noch auf .NET Core laufen, wie etwa ASP.NET Core und Entity Framework Core, die bisher nicht nur in .NET Core, sondern auch auf dem klassischen .NET Framework liefen. In der Version 3.0 erfordern sie aber den .NET Standard 2.1, den es nicht auf dem klassischen .NET Framework gibt – das bleibt bei .NET Standard 2.0 in .NET Framework 4.8 stehen. Auch einige Sprachfeatures in C# 8.0, darunter Ranges, Indexe und asynchrone Streams, erfordern Klassen, die es in .NET Standard 2.0 nicht gibt und die somit in .NET Framework 4.8 nicht verfügbar sind.

Für Entity Framework Core 3.1 hat Microsoft das zwar inzwischen revidiert: die Preview-2-Version von Entity Framework Core 3.1 basiert wieder auf .NET Standard 2.0. Das soll aber der letzte derartige Kompromiss gewesen sein.

Mit dem Umstieg auf .NET Core lässt sich nicht nur Stillstand vermeiden, es gibt auch noch weitere positive Anreize für die Migration:

  1. NET Core ist plattfomunabhängig und nicht wie .NET Framework auf Windows beschränkt. Allerdings gilt diese Aussage nur eingeschränkt. Wenn man die UI-Frameworks Windows Forms und Windows Presentation Foundation (WPF) in .NET Core verwendet (das ist seit Version 3.0 möglich), klebt man auch mit .NET Core auf Windows fest.
  2. .NET Core bietet in vielen Klassen eine höhere Ausführungsgeschwindigkeit. Microsoft hat laut eigener Aussage viel Arbeit in die Leistungsoptimierung der Common Language Runtime (CLR) und der Basisklassen in .NET Core investiert. Basis dafür sind die in .NET Core 2.x/C# 7.x eingeführten neuen Sprachfeatures und Speicherverwaltungsklassen Span<T> und Memory<T>. Auch die modulare Architektur von .NET Core hilft, die Ressourcen des ausführenden Systems zu schonen.
  3. Neben einem vereinfachten Projektformat bietet .NET Core auch zahlreiche Kommandozeilenwerkzeuge, die den Einsatz außerhalb von Visual Studio sowie die Integration in automatisierte DevOps-Prozesse vereinfachen.
  4. Die Verbreitung .NET-Core-basierter Anwendungen ist einfacher, weil Entwickler nicht mehr wie bisher zunächst ein .NET-Framework-Setup ausführen müssen, sondern die komplette .NET-Core-Laufzeitumgebung mit der eigenen Anwendung ausliefern können (Self Contained Deployment). Dadurch lassen sich beliebig viele Versionen der .NET-Core-Laufzeitumgebung auf einem Rechner parallel betreiben. Somit entfällt auch das erneute Testen aller anderen Anwendungen, weil für eine Anwendung nur ein Laufzeitumgebungs-Update erforderlich ist.
  5. Zu guter Letzt finden sich in den .NET-Core-basierten Anwendungsframeworks auch interessante neue Softwarearchitekturen und Konzepte, darunter Razor Pages, Razor Class Librarys, Tag Helper sowie die Entwicklung von Single-Page-Web-Apps mit Blazor.

Wer schon mit .NET Core arbeitet, der weiß, dass .NET Core auch einige Nachteile mit sich bringt. Festzuhalten ist zunächst, dass nicht alle Funktionen aus dem klassischen .NET Framework in .NET Core verfügbar sind. Wie in Abbildung 1 zu erkennen ist, gibt es immer noch rund 50.000 APIs (Microsoft zählt hier nicht Klassen, sondern einzelne Properties und Methoden), die das klassische .NET Framework dem .NET Core voraus hat. Microsoft hat in diesem Zusammenhang angekündigt, dass die Übertragung von APIs aus dem klassischen .NET Framework zu .NET Core abgeschlossen sei. Damit steht fest, dass es nach .NET Core 3.0 keine weitere Übernahme von Funktionen aus .NET Framework zu .NET Core mehr geben wird. Was jetzt nicht drin ist, das bleibt zusammen mit dem klassischen .NET Framework auf dem Abstellgleis zurück (siehe Abbildung 2).

Techniken, die es nicht aus dem klassischen .NET Framework zu .NET Core schaffen, und mögliche Alternativen (Abb. 2).

Fehlende Programmierschnittstellen bedingen auch, dass nicht alle Bibliotheken von Drittanbietern wie einige der grafischen Bibliotheken auf .NET Core laufen können. Das macht eine Umstellung auf .NET Core für betroffene Kunden unmöglich.

Weitere Nachteile in .NET Core sind:

  • .NET Core folgt dem Konzept des Semantic Versioning, das Breaking Changes in Hauptversionen erlaubt. Microsoft hat davon beim Wechsel von .NET Core 1.1 zu 2.0 sowie von 2.2 zu 3.0 jeweils umfassend Gebrauch gemacht, wie die lange Liste der Breaking Changes in Entity Framework Core 3.0 anschaulich zeigt. Anders als beim klassischen .NET Framework kann man sich also in .NET Core nicht darauf verlassen, dass eine einige Jahre alte Anwendung auch noch auf einer aktuellen Version der Runtime lauffähig ist. Versionsumstellungen sind daher mit viel Arbeit verbunden.
  • Erschwerend kommt die radikal verkürzte Support-Dauer hinzu. Beim klassischen .NET Framework gab es in der Regel zehn Jahre Support – Ausnahmen davon betrafen jedoch 4.0, 4.5 und 4.5.1. Bei .NET Core gibt es für ein Long-Term-Support-Release (LTS) drei Jahre Support, für ein Current Release nur drei Monate nach dem Erscheinen des nächsten. Microsoft hat somit den Support für .NET Core 1.0, 1.1 und 2.0 bereits eingestellt. Die Version 2.2 flog am 23.12.2019 aus dem Support. Lediglich die LTS-Version 2.1 wird noch bis Mitte 2021 unterstützt (siehe Abbildung 3). Nicht wenige Nutzer des klassischen .NET Framework haben konservativ agiert und viele Jahre auf die gleiche Version vertraut. Mit .NET Core werden sie zu einer Agilität gezwungen, die sie zumindest bisher nicht wollten.

Support-Dauer der im Umlauf befindlichen .NET Core-Versionen (Abb. 3).

(Bild: Microsoft )

  • Die Dokumentation aller Core-Produkte hat nicht mehr den Umfang, die Tiefe und die Aktualität, die das klassische .NET Framework bot. So finden sich in der Klassendokumentation nur noch kurze Texte und keine Beispiele mehr.
  • Das Nuget-Paketsystem hat trotz aller Verbesserungen der letzten Jahre immer noch technische Probleme (siehe Abbildung 4): Pakete lassen sich nicht installieren oder deinstallieren, oder sich widersprechende Paketversionsanforderungen führen in die "Pakethölle". Für die Paketverwaltung einschließlich der ständigen Nachverfolgung, ob Pakete beispielsweise wegen Sicherheitslücken zu aktualisieren sind, müssen Anwender überdurchschnittlich viel Arbeitszeit einplanen.

Nuget-Bug: Ein Paket ist installiert, wird aber dennoch vom Compiler nicht gefunden (Abb. 4).

Ein Kunde kommentierte diese Mischung aus Agilität und verkürztem Support neulich so: ".NET Core ist nichts für die deutsche Industrie! Wir werden alternative Techniken prüfen müssen". Das beschreibt eindrücklich die Erwartung an Konstanz, die zumindest diese Branche hat. Da aber auch andere Frameworks zur Softwareentwicklung sich inzwischen dem agilen Ansatz verschrieben haben, wird sich auch die deutsche Industrie künftig bewegen müssen – im Zweifelsfall durch mehr Personaleinsatz in der Softwareentwicklung.

Der API-Browser von .NET bietet zu jeder Klasse und jedem Klassenmitglied die Informationen, auf welchen .NET-Varianten die APIs verfügbar sind. Die Migrierbarkeit des eigenen Programmcodes anhand dieser Daten zu ermitteln, erweist sich jedoch als unnötig mühsamer Weg.

Stattdessen empfiehlt sich der Einsatz des Werkzeugs .NET Portability-Analyzer, das zu einem bestehenden .NET Framework-Projekt eine Excel-Datei der in .NET Core nicht unterstützten Klassen und Klassenmitglieder liefert. Zu beachten ist aber, dass das Werkzeug die API-Nutzung aus dem eigenen Quellcode an einen Microsoft-Webservice überträgt und erst dort die Ergebnisse generiert. Anhand eines Windows-Forms-Projekt zeigen die Abbildungen 5 und 6 die Zusammenfassung sowie einen Ausschnitt aus den Detailergebnissen.

Zusammenfassung des .NET Portability-Analyzer für ein Windows Forms-Projekt (Abb. 5).

Die Detailliste zeigt, welche Klassen und Klassenmitglieder in .NET Core 3.0 fehlen (Abb. 6).

Als "Platform Extensions" bezeichnet Microsoft Zusatzklassen für .NET Core, die nicht zum Standardlieferumfang der .NET Core gehören. Dazu zählen insbesondere die .NET Core Windows Desktop Runtime, die Windows Forms und WPF enthält sowie das Windows Compatibility Pack für .NET Core, ein Metapaket, das viele nichtvisuelle Klassen wie den Zugriff auf Registry, Zugriffsrechtelisten, Ereignisprotokoll, Performance-Counter, Systeminformationen, ODBC-Datenbanken, LDAP-Server und Grafikfunktionen sowie das alte Code Document Object Model (CodeDOM) zur Laufzeitcodeauswertung und -generierung umfasst.

Wer heute eine neue .NET-Anwendung startet, sollte dies mit .NET Core tun. Die Agilität der Weiterentwicklung von .NET Core ist ein Fakt, mit dem Entwickler wie auch Anwender lernen müssen zu leben. In der Welt der Webframeworks dreht sich die Uhr noch um ein Vielfaches schneller.

Bei der Evaluierung bestehender .NET Framework-Anwendungen empfiehlt sich eine Unterteilung in diejenigen, die grundsätzlich migrierbar sind und jene, die – zumindest vorerst – nicht migrierbar sind, weil zentrale APIs in .NET Core fehlen.

Im Hinblick auf die so ermittelten migrierbaren Anwendungen gilt es, weiter zu klassifizieren und zwischen denen, die nur noch gelegentlich gewartet werden müssen, und Anwendungen, die sehr aktiv entwickelt werden, zu unterscheiden. Für erstere Gruppe lohnt sich eine Migration allenfalls in Ausnahmesituationen.

Bei den nichtmigrierbaren Applikationen wie Webanwendungen mit ASP.NET Webforms oder SOAP-Server mit Windows Communication Foundation müssen Unternehmen die grundsätzliche Überlegung fällen, ob sich die Investition in eine Neuentwicklung auszahlen.

Am Ende bleibt eine Reihe von Anwendungen, die auf Basis der Zusicherungen von Microsoft weiterhin auf dem klassischen .NET Framework betrieben und auch weiterentwickelt werden können. Der Autor dieses Beitrags selbst hat schon zahlreiche eigene .NET Framework-Anwendungen in diese Kategorie einsortiert.

Nach der grundsätzlichen Entscheidung über einen Umstieg widmen sich die weiteren Teile der Artikelserie konkreten Maßnahmen zu Migrationen verschiedener Anwendungsarten und Bibliotheken, darunter Desktop-Anwendungen mit WPF und Windows Forms, ASP.NET-Webanwendungen, Umstellung des Datenzugriffs von Entity Framework nach Entity Framework Core sowie der Umgang mit WCF-Webservices. Dabei geht es stets um die Frage, was sich migrieren lässt und was nicht, welche Schritte dabei auszuführen sind und welche Werkzeuge helfen.

Dr. Holger Schwichtenberg
ist einer der bekanntesten Experten für .NET und Webtechniken in Deutschland. Zusammen mit 35 weiteren Experten unterstützt er im Rahmen der Firma www.IT-Visions.de mittlere und große Unternehmen durch Beratung und Schulungen beim Erstellen von Windows- und Webanwendungen. Zudem hat er einige Fachbücher zu .NET, PowerShell und JavaScript/TypeScript veröffentlicht. Bei Twitter folgen Sie ihm unter @DOTNETDOKTOR.

(map)