Softwaremigration konkret: .NET -> .NET Core

Eine Betrachtung für eine aktuelle Herausforderung, die immer mehr Firmen betrifft: Die Migration vom klassischen .NET Framework (Versionen bis 4.8.1) zu .NET Core (8LTS)

Kategorie: Migration · 2/5/2024

Softwaremigration konkret: .NET -> .NET Core

Dies ist der vierte Teil einer Serie zum Thema Migration, den Einstieg finden Sie hier.

Nachdem sich die ersten drei Beiträge zum Thema Software-Migration allgemein mit den Gründen, Möglichkeiten und Strategien zum Thema auseinandergesetzt haben, heute eine Betrachtung für eine aktuelle Herausforderung, die immer mehr Firmen betrifft: Die Migration vom klassischen .NET Framework (Versionen bis 4.8.1) zu .NET Core (erste Bezeichnung mit den Long-Term-Support Versionen 2.1 LTS und 3.1 LTS) oder seit 2020 (mit dem Erscheinen von .NET 5.0) nur noch ".NET". Aktuell ist hier seit November 2023 die Version 8 LTS.

Historie des .NET Frameworks

Erstmals wurde das .NET Framework im Jahr 2000 als umfassende Plattform für die Entwicklung von Windows-Anwendungen und später von Web-Anwendungen (ASP, ASP.NET) veröffentlicht. Eine Besonderheit war dabei die Unterstützung verschiedener Programmiersprachen wie C#, VB.NET und F#.
 
Allerdings kristallisierten sich im Laufe der Zeit einige Herausforderungen heraus:
 
  • Monolithische Natur: Das .NET Framework war groß und enthielt viele Komponenten, die nicht immer benötigt wurden (über 10.000 Klassen in über 200 Namespaces).
  • Plattformabhängigkeit: Das klassische .NET Framework ist hauptsächlich auf Windows beschränkt.
.NET Core wurde ab 2016 (V-1.0 LTS) als Antwort auf diese Herausforderungen entwickelt:
  • Es war modularer, sodass Entwickler nur die benötigten Teile (über den Paketmanager NuGet) verwenden konnten.
  • Es war plattformübergreifend und unterstützte Windows, Linux und MacOS.
  • Es war Open Source mit einer aktive Community.
Mit der Veröffentlichung von .NET 5.0 im Jahr 2020 wurde .NET Core dann offiziell in .NET umbenannt. ASP.NET Core und Entity Framework Core folgten demselben Pfad und wurden ebenfalls zu .NET umbenannt.
Dieser Wechsel sollte die Vereinheitlichung der Plattformen und die klare Botschaft vermitteln, dass .NET jetzt die zentrale Plattform für alle Anwendungen ist. Der vorläufig letzte Schritt dieser Zentralisierung wurde mit der Integration der zugekauften Xamarin ("Mono") Plattform zur Unterstützung mobiler Systeme (iOS, Android, ..) in Form des MAUI Frameworks direkt in .NET vollzogen.  
 
Zusammenfassend lässt sich sagen, dass mit .NET 8 ein Stand erreicht wurde, der die Migration großer .NET 4.x Anwendungen deutlich einfacher macht als frühere .NET (Core) Versionen, die Anfangs mit API Änderungen und unvollständigen / fehlenden APIs viel mehr Herausforderungen für eine Migration aufwiesen.

Gründe für die Migration auf die aktuelle .NET (Core) Version

Die Migration eines großen Softwareprojekts vom klassischen .NET Framework zur neuesten Version von .NET Core (jetzt .NET 8) bietet daher mehrere überzeugende Vorteile:
 
  1. Open Source und plattformübergreifende Kompatibilität:
    .NET (Core) ist ein Open-Source-Framework mit Zugriff auf den Quellcode und einer großen Community und damit auch vielen potentiell verfügbaren Entwicklern. Es lassen sich Anwendungen für die Zielplattformen Windows, MacOS, Linux sowie für mobile Geräte erstellen. Windows, MacOS, Linux können dabei auch als Entwicklungsplattform fungieren. Hinweis: Das Visual Studio 2022 for Mac ist zwar zum 31. August 2024 abgekündigt, kann jedoch relativ problemlos durch Visual Studio Code ersetzt werden.
  2. Modularität und geringerer Ressourcenverbrauch:
    .NET (Core) folgt (über den Paketmanager NuGet) einem modularen Ansatz, der es ermöglicht, nur die erforderlichen Funktionen und APIs in Ihre Anwendung einzubeziehen. Dies führt zu einem kleineren Anwendungs-Footprint. Damit sind schlankere und schnellere Anwendungen möglich.
  3. Verbesserte Leistung: .NET (Core) ist auf Leistungsoptimierung ausgerichtet. Es bietet durch sehr viele Optimierungen seitens Microsoft eine bessere Ausführungsgeschwindigkeit, reduzierten Speicherverbrauch und verbesserte Skalierbarkeit im Vergleich zum älteren .NET Framework. Anwendungen, die auf .NET (Core) basieren, weisen in Szenarien mit hoher Parallelität oder hoher Arbeitsbelastung in der Regel eine bessere Leistung auf. Dies ist durchaus auch in der Anwendererfahrung zu spüren, wenn Anwendungen einfach "flüssiger" laufen.
  4. Größere Skalierbarkeit: .NET (Core)-Anwendungen können mehr gleichzeitige Anfragen verarbeiten, da sie leichtgewichtiger sind, Ressourcen effizient nutzen und neue Features wie native Kompilierung bieten. Wenn Ihr Softwareprojekt horizontal skalieren muss (z. B. bei einer Microservices-Architektur), ist .NET (Core) unserer Erfahrung nach daher die bessere Wahl. Bei bestimmten Projekten (z.B. Radius Authentifizierung) konnten wir bei evanto auf Standard-Hardware damit Durchsätze von mehreren tausend Requests pro Sekunde erzielen.
  5. Moderne Entwicklungserfahrung:
    .NET (Core) integriert sich nahtlos in moderne Entwicklungstools wie Visual Studio Code (kostenfrei) und Visual Studio 2022. Damit ist ein effizienter Zugriff auf die neuesten Sprachfunktionen, Bibliotheken und Tools und eine hohe Entwicklerproduktivität möglich. Genauso ist die Qualität der Dokumentation auf hohem Niveau, es finden sich außerdem durch die weite Verbreitung zahllose Ressourcen im Web. Neu und effizient ist die direkte KI Integration über GitHub Copilot direkt in den Entwicklungsumgebungen, die eine deutliche Erleichterung der bei der Bearbeitung repetitiver Aufgaben bringt.
  6. Langzeitunterstützung (LTS):
    Mit der Veröffentlichung von .NET 8 hat Microsoft sich zur langfristigen Unterstützung (LTS) für .NET Core verpflichtet. Dadurch erhalten Anwendungen über einen planbaren, längeren Zeitraum Sicherheitsupdates und Fehlerkorrekturen (bei LTS Versionen jeweils über 3Jahre, bei .NET 8 bis zum 10.11.2026).
  7. Kosteneinsparungen und Talentpool:
    .NET (Core) reduziert die Lizenzkosten, da es multi-plattform Open Source ist und keine teuren Windows Server-Lizenzen erfordert. Dies ist unserer Erfahrung nach mit dem Auslaufen des Supports für den weit verbreiteten Windows Server 2012R2 ein wichtiger Aspekt, da nach einer Migration Anwendungen vergleichsweise einfach auf einer Linux Serverumgebung oder in einer containerbasierten Umgebung (Docker, Podman, K8S) gehostet werden können.
    Ebenfalls wichtig: Obwohl derzeit  noch genügend Entwickler im Talentpool für das .NET Framework vorhanden sind, verschiebt sich der Trend hin zu .NET (Core), da Entwickler lieber mit neueren Technologien arbeiten.
  8. Zukunftssicherheit:
    Die Funktionalität des klassischen .NET Frameworks wurde durch Microsoft auf dem aktuellen Stand eingefroren, Innovationen und Erweiterungen finden nur noch in .NET (Core) statt. Es gibt Stand Anfang 2024 bereits sehr viele wichtige Erweiterungen, wie Blazor, ASP.NET Minimal APIs, MAUI, OpenTelemetry, Aspire, GRPC etc., die nur noch in .NET (Core) verfügbar sind. Ebenso sind Spracherweiterungen wie Spans sowie neue Funktionen des Garbage Collectors (GC) und des JiT Compilers (DATAS, Dynamic PGO, weitere) nur in .NET (Core) verfügbar. Ein weiterer wichtiger Aspekt ist, dass auch die Unterstützung vieler Drittanbieter nachlässt.    
 
Damit ist eine Migration auf .NET (Core) nahezu unverzichtbar für Anwendungen, die zukunftssicher sein sollen.

Weggefallene Bestandteile des .NET Frameworks

.NET (Core) bildet alle wichtigen Funktionalitäten des klassischen .NET Frameworks ab, allerdings gibt es eine (vergleichsweise kleine) Auswahl von Teilbereichen / APIs / Technologien die nicht mehr zur Verfügung stehen und anders realisiert werden müssen. Grund dafür sind meist neuere verfügbare Technologien und effizientere Ansätze, die aktuell möglich sind. Dies sind insbesondere:
 
  • ASP.NET Web Forms: Eine Migration ist hier z.B. nach ASP.NET Razor Pages möglich.
  • Die Windows Communication Foundation (WCF): Dieses Framework wurde oft für SOAP Services eingesetzt, diese sind nach wie vor über ASP.NET WebApps möglich, alternativ wäre ggf. die Migration hin zu REST oder gRPC Webservices zu prüfen (besonders wenn [WebGetAttribute], [WebInvokeAttribute] verwendet wurde).  Andere Anwendungsfälle (Server) können mit relativ wenig Anpassungsaufwand mittels der CoreWCF Bibliothek migriert werden.
  • Die Windows Workflow Foundation (WF): Hier ist keine direkte Migration innerhalb .NET (Core) möglich, hier ist entweder eine alternative Workflow Engine (z.B. ELSA, Wexflow) möglich oder ein Ersatz durch "klassische" Programmierung. Unter Einbeziehung von Azure wäre alternativ eine Migration hin zu Durable Functions möglich.
  • Objektserialisierung via BinaryFormatter (als deprecated gekennzeichnet). Ein Ersatz ist - abhängig von der Einsatzart - meist über System.Text.Json, NewtonSoft.Json oder weitere Tools möglich.
  • Das Entity Framework 6 wurde komplett neu implementiert, die visuellen EDMX Modelle sind dabei weggefallen.  Daher müssen diese entweder über den Datebase first Ansatz (automatische Erstellung eines Modells aus der Datenbankstruktur) oder Code first Ansatz (Generierung der Datenbank aus C# Modellklassen + Kontext) ersetzt werden.
  • Weitere Windows only APIs wie Unterstützung für ODBC, Drawing, Windows Registry, Event Log, Windows Services etc. Vieles kann - zumindest für die Runtime Platform Windows über den Windows Compatibility Pack (s.u.) nachgerüstet werden, besser ist jedoch eine Neuimplementierung mit Multiplatform Support (falls möglich).
  • Nicht ersetzbar sind AppDomains.
  • Weitere nicht mehr verfügbare Technologien wie .NET Remoting finden sich hier.
 
Andere, komplexere .NET Bestandteile wie ASP.NET MVC sind nach wie vor vorhanden, weisen aber in Teilaspekten Änderungen und neue Features auf (z.B. Tag Helper, Ersatz von @Html.Action() durch ViewComponents, Filter, etc.).
 
Für ein Migrationsvorhaben sind ebenfalls alle Drittanbieter-Bibliotheken auf Vorhandensein / Kompatibilität (API-Änderungen) zu prüfen und ggf. zu ersetzen.  Teilweise sind Funktionalitäten, die bisher über Drittanbieterbibliotheken umgesetzt werden mussten (z.B. Dependency Injection via AutoFac, LightCore oder Ninject) nunmehr schneller und effizienter direkt in .NET (Core) verfügbar. Hier sind ggf. die Einstellungen zum Objektlebenszyklus (Singleton, Scoped, Transient..) zu prüfen.
 
Bei weiteren Aspekten, wie der z.B. der Anwendungskonfiguration, sind bisherige Mechanismen (z.B. der ConfigurationManager) weiterhin verfügbar, neue Möglichkeiten wie IConfiguration sind aber ungleich flexibler, so dass hier eine Umstellung sehr sinnvoll ist.   

Optionen für die UI Migration

Unter .NET (Core) 8 gibt es deutlich mehr Möglichkeiten für die Realisierung von Anwendungs-UIs als noch im klassischen .NET:
 
  • ASP.NET Core Blazor: Ein Framework für die Erstellung von interaktiven Web-UIs mit C# und HTML. Blazor ermöglicht es, clientseitige Logik in .NET zu schreiben, ohne JavaScript zu verwenden. Blazor unterstützt sowohl serverseitiges Rendering als auch WebAssembly, um die UIs im Browser auszuführen. Blazor bietet Komponenten, Routing, Dependency Injection und andere Features, die die Webentwicklung erleichtern. Neu in .NET 8 ist der "Auto Render Mode" der auf Komponentenebene automatisch entscheidet, ob SSR (Server Side Rendering) oder CSR (Client Side Rendering) für eine Komponente notwendig ist.
  • MAUI: Eine plattformübergreifende UI-Technologie, die auf Xamarin.Forms basiert. MAUI steht für Multi-platform App UI und ermöglicht es, native UIs für Windows, macOS, Android und iOS mit einer einzigen Codebasis zu erstellen. MAUI verwendet XAML als UI-Markup-Sprache und bietet eine Vielzahl von Steuerelementen, Layouts und Stilen, die sich an die jeweilige Plattform anpassen.
  • WinUI 3: Eine moderne UI-Technologie für Windows-Apps, die auf dem Windows UI Framework (UWP) aufbaut. WinUI 3 bietet eine Reihe von UI-Steuerelementen, Animationen, Effekten und anderen Features, die die Windows-App-Entwicklung verbessern. WinUI 3 ermöglicht es, sowohl Desktop- als auch UWP-Apps mit dem gleichen UI-Code zu erstellen, und unterstützt auch die Integration mit anderen UI-Technologien wie WPF und WinForms.
  • ASP.NET Minimal APIs: Mit Fokus auf Einfachheit, Kompaktheit und Performance steht jetzt auch eine NodeJS ähnliche Entwicklungsweise für Web Anwendungen zur Verfügung. Ein wichtiger Vorteil ist hier die Möglichkeit der nativen AOT (Ahead of Time) Kompilierung, die zu signifikanten Performancezuwächsen führt.

 

Außerdem sind auch noch die "klassischen" Technologien wie:
 
  • WinForms: Einfache UI Technologie ohne MVVM Datenbindungsmechanismen, die nach wie vor beliebt ist. WinForms ist nicht multiplattformfähig und nur unter Windows verfügbar
  • Windows Presentation Foundation (WPF): Modernere UI Technologie - basierend auf MVVM Datenbindung, die mit dem .NET Framework 3.5 eingeführt wurde und auch in .NET 8 verfügbar ist. Allerdings bestehen hier Zweifel an der Zukunftssicherheit, da WPF auch eine Windows only-Technologie ist.
  • ASP.NET MVC: Das MVC (Model View Controller) Framework ist noch wie vor ein bevorzugtes Mittel der Wahl für die Realisierung von komplexen Webanwendungen da sich neue Technologien/Erweiterungen wie Minimal APIs oder Razor Pages primär auf die schnelle Umsetzung weniger komplexer Aufgabenstellungen fokussieren.
verfügbar. Daneben existieren auch noch eine Reihe von Third Party UI Technologien wie UNO Platform oder Avalonia für die Realisierung von Multiplatform-Apps.
 
Möglich ist jederzeit auch einen ASP.NET Backend Service mit einer bewährten Technologie zur Erstellung von Single Page Applications (SPA) zu verbinden und das Frontend über
 
zu erstellen.
 
Eine Migration ist daher bei folgenden Ausgangstechnologien empfehlenswert oder, wenn nicht mehr verfügbar (s.o.), Pflicht:
 
  • ASP.NET Web Pages -> z.B. Razor Pages
  • WinForms -> WinUI 3 oder zu einer Web UI (MAUI, Blazor, ASP.NET)
  • WPF -> WinUI 3 oder zu einer Web UI (MAUI, Blazor, ASP.NET)

Anpassungsbedarf ergibt sich auch bei (nach wie vor) bestehenden Frameworks wie ASP.NET MVC, so z.B. mit Owin-Controllern und Start-Klassen:

  • Namespace System.Web.Http/Mvc wird zu Microsoft.AspNetCore.Mvc
  • Basisklasse ApiController -> Controller
  • HttpRequest, HttpResponse, HttpResponseException ersetzen
  • IHttpActionResult durch IActionResult ersetzen
  • HttpContext.Current steht nicht mehr zur Verfügung
  • Anpassungen sind auch beim Dateiupload erforderlich (alt: HttpPostedFileBase, neu IFormFile oder MultiPartReader)
  • ASP.NET Core verwendet System.Text.Json statt NewtonSoft.Json für die Serialisierung, so dass spezielle NewtonSoft.Json Artefakte wie JObject oder JToken vermieden werden sollten (NewtonSoft.Json kann aber nach wie vor eingebunden werden). 

Tools zur Migrationsunterstützung

Die folgenden Microsoft Tools sind zur Migrationsunterstützung verfügbar:
 
  • .NET Upgrade Assistant: Dies ist eine Visual Studio Erweiterung und ein Befehlszeilen-Tool, das bei der Aktualisierung von Apps auf die neueste Version von .NET unterstützt. Es unterstützt verschiedene Sprachen, Projekttypen und Upgrade-Pfade, wie z.B. von .NET Framework zu .NET, von .NET Core zu .NET, von UWP zu WinUI 3 oder von Xamarin Forms zu .NET MAUI. Es kann auch einige Änderungen an Ihrem Projekt und Ihrem Code vornehmen, um einige inkompatible Änderungen zu beheben und neuere Funktionen zu nutzen.
  • Platform Compatibility Analyzer: Bestandteil des .NET SDK (einer der Roslyn Code Quality Analyzers) zur Vorabprüfung welche APIs im Projekt nicht multiplattformfähig sind.
  • Windows Compatibility Pack: Dies ist ein NuGet-Paket, das einen großen Teil der nicht in .NET (Core) enthaltenen .NET Framework APIs für .NET bereitstellt. Dies betrifft vor allem APIs die sich auf Windows-spezifische Technologien verlassen, wie z.B. die Windows-Registrierung oder das GDI+ Zeichenmodell.
 
Wichtig ist hier, dass der Upgrade Assistant zwar einige Arbeit, z.B. bei der Konvertierung der Projektdateien in das neue Format, abnehmen kann, vieles jedoch im Nachgang per "Handarbeit" zu erledigen ist (z.B. Ersatz von Bibliotheken und Diensten, die nicht (mehr) für .NET (Core) verfügbar sind).
 

Planung einer .NET Core Migration

Ergänzend zu den im vorherigen Artikel "Phasen eines Software-Migrationsprojektes" genannten Schritten sind bei .NET Anwendungen in der Detailkonzeptphase folgende Aspekte wichtig:
 
  • (Externe) Abhängigkeitsprüfung, welche Third Party-Bibliotheken stehen nicht mehr für .NET 8 zur Verfügung?
  • Prüfen, welche Applikationsbestandteile automatisch migriert werden können, z.B. mit Hilfe des .NET Upgrade Assistant (s.o.)
  • Detailanalyse zur Migration anhand der in der zu migrierenden Anwendung enthaltenen Bestandteile und APIs (z.B. ASP.NET Änderungen)
  • Konzept für die Verwendung neuer APIs und Features in .NET (Core), z.B. für Cross Cutting Concerns wie Logging, Tracing, Dependency Injection, Authentifizierung etc.
  • Untersuchungen bzgl. Multiplattformfähigkeit, es ist nicht nur die Cross Platform-Verfügbarkeit aller APIs zu prüfen, sondern z.B. auch die Verwendung "hart" codierter Pfade und Dateisystemzugriffe, da in UNIX basierten Systemen z.B. andere Pfadtrennzeichen verwendet werden und Verzeichnis- bzw. Dateinamen Case Sensitiv sind.
  • Ggf. Anpassung der Test- und Deploymentstrategie (Prüfung neuer Optionen wie Container-basiertes Deployment, Azure Cloud Deployment)
  • Ggf. Anpassung von Entwicklerplattform und -tools, Prüfen der Lizenzausstattung (z.B. Github Copilot), Hardwareanforderungen für Entwickler Workstations (besonders bei Nutzung mobiler Entwicklungstools / MAUI)
  • Ggf. Bereitstellung von Testhardware (mobile Entwicklung)
  • (Interne) Abhängigkeitsanalyse - und darauf basierend eine Reihenfolge der Umsetzung aller zum Projekt gehörenden Assemblies

Da meist nicht auf die Weiterentwicklung des bestehenden (klassischen) .NET-Systems während der Migrationsphase verzichtet werden kann, kommt eine Big Bang-Migration (die Umstellung in einem Schritt) oft nicht in Frage, da sonst alle Änderungen im bestehenden System jeweils in den bereits migrierten Anwendungsteilen nachvollzogen werden müssen. Für eine schrittweise Migration (Feature bei Feature) sind unter .NET die im Bild gezeigten Ansätze möglich:

  • Die Verwendung von .NET Standard Bibliotheken: .NET Standard bezeichnet dabei einen gemeinsamen API Umfang der sowohl in .NET 4.x als auch in .NET (Core) zur Verfügung steht. Assemblies im bestehenden System werden mit dem Moniker (Zielumgebung) netstandard-2.x kompiliert und sind danach sowohl in der bestehenden Anwendung als auch im .NET Core Projekt einsetzbar. Nachteil: .NET Standard 2.x bildet nur einen Teilumfang der unter .NET (Core) zur Verfügung stehenden Möglichkeiten ab.
  • Multi-Targetting: Als Target-Frameworks in einer Assembly-Projektdatei werden sowohl die Moniker net48 als auch net8.0 eingetragen, (noch nicht migrierte) Unterschiede werden über konditionale Kompilierung aufgefangen. Sind sehr Windows-nahe Bibliotheken umzustellen, kann als Moniker auch net8.0-windows eingesetzt werden. Hier stehen auch Windows-spezifische APIs zur Verfügung, die Multiplattformfähigkeit ist allerdings erst dann gegeben, wenn diese plattformunabhängig migriert wurden. Nachteil: Erhöhter Aufwand durch mehrere Migrationsschritte, bedingte Kompilierung.
  • Services: Die Architektur der bisherigen Anwendung wird vor Migration so angepasst, dass wichtige / alle (Backend) Funktionalitäten per Service verfügbar gemacht werden, die dann im Laufe der Migration schrittweise auf .NET (Core) umgestellt werden können und in der Zwischenzeit sowohl der bisherigen Anwendung (UI) als auch den bereits migrierten Anwendungsteilen zur Verfügung stehen. Nachteil: Eingriff/Änderung der bestehenden Anwendung vor Migration notwendig. 

 

Wir helfen gerne bei dieser komplexen Problematik!

*Datenschutz

Eine Weitergabe an Dritte findet grundsätzlich nicht statt, es sei denn, dass wir dazu gesetzlich verpflichtet sind. Sie können Ihre erteilte Einwilligung jederzeit mit Wirkung auf die Zukunft widerrufen. Im Falle des Widerrufs werden Ihre Daten umgehend gelöscht. Ihre Daten werden ansonsten gelöscht, wenn wir Ihre Anfrage bearbeitet haben oder der Zweck der Speicherung entfallen ist. Sie können sich jederzeit über die zu Ihrer Person gespeicherten Daten informieren. Weitere Informationen finden Sie in der Datenschutzerklärung.

Dr. Sven von Känel

Dr. Sven von Känel

Geschäftsführer, Ihr Ansprechpartner .NET Core / Angular

  • svk@evanto.de
  • 0941 / 94592-20

Über uns

Ein erfahrenes Entwicklerteam, das mit Leib und Seele Software erstellt.

evanto logo

Kontaktdaten

Brunnstr. 25,
Regensburg

+49 (941) 94592-0
+49 (941) 94592-22

Statistik