Checkliste vor der Migration von .NET Framework zu .NET

· · .NET, .NET Framework, C#, Modernisierung, Windows-Entwicklung, Migration

Excel-Checkliste mit japanisch-englischen Tabellenblättern herunterladen

Diese Datei besteht aus den beiden Tabellenblättern Checklist-ja und Checklist-en und bildet die Vorab-Checkliste aus 13 Kapiteln in 7 Kategorien mit 34 Punkten ab: Ausrichtung / Vorbereitung der aktuellen .NET-Framework-Seite / Anwendungstyp und Technologiewahl / nicht unterstützte Technologien und kritische APIs / Windows-exklusive Abhängigkeiten / Shared Library und Datenzugriff / Betrieb und Build. Die Spalten Status und Notes bleiben leer, sodass sich die Datei direkt als projektspezifische Bestandsaufnahme-Tabelle verwenden lässt. Ein Blick darauf vor der Lektüre erleichtert es, den roten Faden bis Kapitel 13 zu erfassen.

TargetFramework in der .csproj auf net10.0 ändern, ein paar NuGet-Pakete aktualisieren, und sobald der Build durchläuft, ist man fertig.

… Wäre die Migration wirklich so, wäre das ziemlich entspannt. In der Praxis läuft es meistens anders.

In .NET-Framework-Projekten schlummern gewöhnlich mehrere unbewusste Annahmen: System.Web, WCF, Web Forms, alte packages.config-Dateien, web.config.install.xdt, native DLLs, COM / ActiveX, Drittanbieter-Steuerelemente, die nur zur Entwurfszeit funktionieren, implizite x86-Annahmen, Designer-abhängige ResX-Dateien, alte Serialisierer und mehr.

Deshalb ist bei einer Migration von .NET Framework zu .NET wirklich entscheidend: die Bestandsaufnahme vor dem Beginn der Umsetzung. Lassen sich die Themen vorab in Einzelfragen zerlegen, wird die Migration nicht zu einer „großen Wette“, sondern zu einer „Liste von Punkten, die man der Reihe nach abarbeitet“.

Dieser Artikel fasst zusammen, was Sie prüfen sollten, bevor Sie eine bestehende .NET-Framework-4.x-Geschäftsanwendung auf aktuelles .NET migrieren. Die wichtigsten Zielgruppen sind etwa:

  • Klassenbibliotheken
  • Konsolenanwendungen
  • Windows-Dienste
  • WinForms / WPF
  • ASP.NET Framework (MVC / Web API / Web Forms)
  • Anwendungen, die WCF verwenden
  • Anwendungen, die EF6 verwenden

Dieser Artikel wurde am 15.03.2026 verfasst. Da sich Supportzeiträume und Empfehlungen der offiziellen Tools ändern, prüfen Sie bei größerem zeitlichen Abstand bitte zusätzlich die offiziellen Informationen.

1. Das Wichtigste zuerst

Zu Beginn nur die Schlussfolgerungen, die sich kaum widerlegen lassen.

  • Vor der Migration zuerst die .NET-Framework-Seite aufräumen. Auch Microsofts offizieller Leitfaden empfiehlt, vor dem Portieren auf .NET Framework 4.7.2 oder höher zu wechseln und vorab die Umstellung auf PackageReference, den SDK-Stil und die Aktualisierung der Abhängigkeiten abzuschließen.
  • Der Schwierigkeitsgrad wird eher vom Anwendungsmodell als von der Codemenge bestimmt. Klassenbibliotheken und Konsolenanwendungen sind vergleichsweise leicht; ASP.NET Framework, Web Forms, WCF-Server und WF (Workflow Foundation) neigen dazu, aufwendig zu sein.
  • WinForms / WPF bleiben auch nach der Migration zu .NET Windows-exklusiv. Wer das missversteht, tappt in die klassische Falle, nach der Migration festzustellen, dass die Anwendung nicht in einem Linux-Container läuft.
  • ASP.NET Framework → ASP.NET Core ist faktisch eine Architekturmigration. Kleine Anwendungen lassen sich manchmal in einem Rutsch umstellen, aber bei großen Produktivsystemen ist es sicherer, von einer stufenweisen Migration auszugehen.
  • WCF und EF6 lassen sich mitunter von der Runtime-Migration entkoppeln. Für WCF-Clients gibt es unterstützte Pakete für .NET, und EF6 kann nach dem Umzug auf modernes .NET separat zu EF Core migriert werden.
  • Demgegenüber sind die Erstellung von AppDomains, .NET Remoting, CAS (Code Access Security), COM+, Workflow Foundation und Abhängigkeiten von BinaryFormatter Rotlichter. Werden sie nicht frühzeitig gefunden, explodiert der Aufwand später.
  • packages.config / install.ps1 / XDT (XML Document Transform, der Mechanismus, mit dem z. B. web.config transformiert wird) / content-Assets / native DLLs / COM / ActiveX / x86-Annahmen fallen häufig zur Laufzeit oder zur Entwurfszeit aus, selbst wenn der Build erfolgreich ist — deshalb vor dem Start durchleuchten.
  • Stand März 2026 ist .NET 10 die LTS-Version. Für einen neuen Migrationszielpunkt ist es naheliegend, sich grundsätzlich an der aktuellen LTS-Version zu orientieren.
  • Eine Migration ohne Tests, Messungen und Rollback-Vorbereitung ist gefährlich. Migration ist weniger eine Implementierungsaufgabe als die Arbeit, Voraussetzungen eine nach der anderen sichtbar zu machen.

2. Zuerst klären: Sollte überhaupt jetzt migriert werden?

Die erste Entscheidung betrifft nicht „wie migriert wird“, sondern ob diese Anwendung wirklich jetzt migriert werden sollte.

Bleibt das unklar, entsteht leicht entweder eine technisch korrekte, aber geschäftlich zu schwere Migration — oder umgekehrt eine viel zu lange Verzögerung, obwohl die Migration eindeutig sinnvoll wäre.

2.1 Der Verbleib bei .NET Framework ist eine ganz normale Option

.NET Framework 4.8.1 wird weiterhin unterstützt, solange es auf einem unterstützten Windows läuft. Es ist also nicht so einfach, dass sofort Gefahr droht, wenn nicht augenblicklich alles auf modernes .NET umgestellt wird.

Allerdings bringt der Verbleib klare Einschränkungen mit sich.

  • Sie kommen nicht aus der Windows-Bindung heraus
  • Sie tragen weiterhin ASP.NET Web Forms und alte Server-Stacks mit sich
  • Sie profitieren kaum von den Leistungsverbesserungen, Sprachfunktionen und dem Ökosystem des neueren .NET
  • Sie driften leicht von den heutigen Annahmen zu Cloud, Containern und CI/CD ab

Sind umgekehrt solche Abhängigkeiten stark ausgeprägt, ist es sinnvoll, vorerst auf .NET Framework 4.8.1 zu setzen, stabil weiterzubetreiben und die Ablösung auf einer separaten Schiene zu planen.

  • Ein großer Bestand an Web-Forms-Bildschirmen
  • Die WCF-Serverkompatibilität muss streng eingehalten werden
  • Tiefe Abhängigkeiten von Workflow Foundation oder COM+
  • Drittanbieter-Designer-Komponenten unterstützen modernes .NET nicht
  • Größere fachliche Spezifikationsänderungen sind geschäftlich nicht zulässig

2.2 Was sich je nach Option ändert

Option Was wird besser Was bleibt / was geht verloren Geeignet für
Bei .NET Framework 4.8.1 bleiben Bestehende Assets bleiben unangetastet, stabiler Betrieb leicht möglich Windows-exklusiv, altes Anwendungsmodell, Grenzen der Modernisierung Starke Legacy-Abhängigkeiten, Geschäftspriorität liegt derzeit auf stabilem Betrieb
Migration zu modernem .NET, aber Verbleib unter Windows Runtime und Toolchain lassen sich modernisieren. Große Gewinne bei Leistung, Entwicklererfahrung und SDK-Stil Windows-API-Abhängigkeiten bleiben bestehen. Nicht plattformübergreifend WinForms / WPF, Windows-Dienste, Geschäftsanwendungen mit Windows-APIs
Migration zu modernem .NET mit Linux / Container / Cloud im Blick Mehr Freiheit bei den Deployment-Zielen. Auch das Betriebsmodell lässt sich leichter erneuern Windows-exklusive APIs und das Anwendungsmodell müssen zuerst entfernt werden Serverseite soll in Richtung Cloud verschoben werden, Infrastruktur soll ebenfalls erneuert werden

Entscheidend ist, zuerst nicht ob Sie migrieren wollen, sondern wo Sie nach der Migration landen wollen festzulegen.

3. Vier Grundsatzentscheidungen, die vorab zu treffen sind

3.1 Die Ziel-.NET-Version

Zum Zeitpunkt der Erstellung ist gemäß Microsofts Supportrichtlinie .NET 10 die LTS-Version. Gleichzeitig endet der Support sowohl für .NET 8 LTS als auch für .NET 9 STS planmäßig am 10.11.2026.

Dass eine STS-Version dasselbe Datum wie eine LTS-Version erreicht, liegt daran, dass der STS-Supportzeitraum von 18 auf 24 Monate verlängert wurde. Rechnet man noch mit der früheren Annahme „STS = 18 Monate“, käme man für .NET 9 auf ein Supportende am 12.05.2026 — prüfen Sie Datumsangaben deshalb stets gegen die offizielle Lebenszyklus-Übersicht.

Wer jetzt neu von .NET Framework migriert, sollte deshalb ohne besonderen Grund natürlicherweise die aktuelle LTS-Version als Zielpunkt wählen.

Die praktische Überlegung dabei ist einfach.

  • Bei einer kleinen Migration, die schnell erledigt sein soll, direkt auf der aktuellen LTS landen
  • Auch bei Kernsystemen für den langfristigen Betrieb die aktuelle LTS als Basis ansetzen
  • „Wegen einer bestehenden Bibliothek soll es die vorherige LTS-Version sein“ ist ein legitimer Grund, aber prüfen Sie anhand des Datums, wie lange sie noch gepflegt wird

3.2 Windows-exklusiv bleiben oder künftig plattformübergreifend werden?

Diese Entscheidung verändert grundlegend, welche Punkte Sie betrachten müssen.

  • Bleiben Sie Windows-exklusiv, können Sie den pragmatischen Weg gehen, zunächst mit WPF / WinForms und dem Windows Compatibility Pack nur die Runtime zu modernisieren.
  • Streben Sie künftig Linux / Containerisierung an, müssen Sie Windows-gebundene APIs wie System.Drawing.Common, die Registry, WMI, EventLog, Windows-Dienste, COM und Office Interop frühzeitig inventarisieren.

Beginnen Sie die Migration, ohne das entschieden zu haben, verdreht sich die Diskussion mittendrin: „War Windows-fest eigentlich in Ordnung?“ – „Nein, wir wollten das doch in Container packen.“

3.3 Alles auf einmal oder stufenweise?

Es gibt im Wesentlichen drei Migrationsformen.

  • Eine nahezu In-Place-Komplettmigration
  • Eine Side-by-Side-Migration, bei der Alt und Neu parallel laufen
  • Eine stufenweise Migration, die Route für Route bzw. Bibliothek für Bibliothek nach und nach umzieht

Besonders bei ASP.NET-Framework-Anwendungen empfiehlt Microsofts Leitfaden ausdrücklich die inkrementelle Migration. Wenn die Produktion nicht angehalten werden soll, es viele Funktionen und viele umgebende Abhängigkeiten gibt, ist es weniger belastend, von Anfang an auf eine stufenweise Migration zu setzen.

3.4 Was aus dieser Migration ausgeschlossen wird

Migrationen scheitern oft, weil zu viel auf einmal angepackt wird.

Zum Beispiel wird es meist schwer, Folgendes gleichzeitig zu erledigen:

  • .NET Framework → .NET
  • ASP.NET Framework → ASP.NET Core
  • EF6 → EF Core
  • Windows-Server → Linux-Container
  • Änderung der Authentifizierungsinfrastruktur
  • Änderung der Logging- / Überwachungsinfrastruktur
  • Datenbankmigration

Natürlich mag irgendwann alles davon nötig sein. Ob es aber gleichzeitig erledigt werden muss, ist eine andere Frage.

In der Praxis funktioniert es besser, wie folgt zu trennen:

  1. Zuerst Runtime und Projektstruktur modernisieren
  2. Danach das Anwendungsmodell umziehen
  3. Zuletzt ORM, Authentifizierung, Cloud und Überwachung aktualisieren

4. Das Fundament, das vor dem Start herzustellen ist

Microsofts Leitfaden zum Vorbereiten des Portierens ist ziemlich praxisnah. Kurz gesagt: Bringen Sie Ihre aktuellen .NET-Framework-Projekte vor der Migration auf einen modernen Ausgangspunkt.

4.1 Auf .NET Framework 4.7.2 oder höher wechseln

Der offizielle Leitfaden empfiehlt, vor dem Portieren .NET Framework 4.7.2 oder höher als Ziel zu wählen. Der Grund: Auch wenn .NET Standard eine bestehende API nicht unverändert übernimmt, lässt sich so leichter auf neuere API-Alternativen umsteigen.

In der Praxis ist es klarer, nach Möglichkeit 4.8.1 als Basis anzusetzen.

  • Aus Support-Sicht die naheliegende Wahl
  • Lässt sich gut als letzter stabiler Punkt auf der .NET-Framework-Seite behandeln
  • Erleichtert die Ausrichtung „zuerst auf der aktuellen Framework-Seite aufräumen“

Was sich ändert, wenn Sie das vorab erledigen

  • Der Umgang mit .NET Standard 2.0-Shared-Libraries wird leichter stabil
  • Rauschen aus der alten Runtime lässt sich vorab reduzieren
  • Es wird leichter zu unterscheiden, ob ein Kompatibilitätsproblem an „der Alterung des Frameworks“ oder an „der Umstellung auf modernes .NET“ liegt

4.2 Auf PackageReference umstellen

Der Leitfaden zum Vorbereiten des Portierens empfiehlt, Verweise auf das Format PackageReference umzustellen. Erledigen Sie das vorab, verbessert sich der Überblick über das Abhängigkeitsmanagement deutlich.

Was sich mit PackageReference ändert

  • Paketverweise werden in der csproj gebündelt
  • Transitive Abhängigkeiten werden besser sichtbar
  • Die Voraussetzungen für das Restore gleichen sich an die moderne .NET-Seite an
  • Bessere Kompatibilität mit CLI / CI

Allerdings lauern hier Fallstricke.

Typische Fallstricke

Die offizielle NuGet-Dokumentation nennt ausdrücklich diese Einschränkungen für die Migration von packages.config zu PackageReference:

  • Die integrierte Migration von Visual Studio funktioniert nicht bei ASP.NET-Projekten
  • Pakete, die von install.ps1 / uninstall.ps1 abhängen, funktionieren mitunter nicht wie erwartet
  • Assets im content-Ordner werden mitunter ignoriert
  • XDT-Transformationen wie web.config.install.xdt werden nicht angewendet
  • Pakete mit alter Assembly-Struktur direkt unter lib lassen sich mitunter nicht sauber auflösen

Mit anderen Worten: Denken Sie nicht, es handle sich nur um einen Wechsel des Paketformats. Besonders im klassischen ASP.NET war es üblich, dass NuGet-Pakete bei der Installation web.config umschreiben, weshalb implizite Annahmen bei der Migration leicht sichtbar werden.

Womit umstellen

Es geht nicht nur mit Handarbeit. Allerdings unterscheidet sich der Zuständigkeitsbereich je nach Werkzeug.

Werkzeug Was es kann Voraussetzungen und Hinweise
Die Umstellungsfunktion von Visual Studio Mit Rechtsklick im Projektmappen-Explorer auf „Verweise“ oder packages.config und Auswahl von Migrate packages.config to PackageReference... wird umgestellt Ab Visual Studio 2017 15.7. Nicht nutzbar bei ASP.NET- und C++-Projekten. Erscheint der Menüpunkt nicht, einmal die NuGet-Wiederherstellung oder den Paket-Manager öffnen und dann erneut rechtsklicken
.NET Upgrade Assistant Führt Analyse und Upgrade des Projekts gebündelt durch Laut offizieller Dokumentation nicht mehr empfohlen — verwiesen wird auf GitHub Copilot App Modernization
GitHub Copilot App Modernization Unterstützt von Bewertung über Planung und Codeänderungen bis zur Validierung. Zentraler Bestandteil der aktuellen offiziellen Empfehlung Setzt gemäß 4.5 Visual Studio, Copilot und C#-Code voraus
Manuelle Umstellung auf SDK-Stil Eine neue csproj anlegen und nur die nötigen Einträge übernehmen Bei Projekten mit wenigen Dateien mitunter der schnellste Weg

Die Umstellungsfunktion von Visual Studio legt vor der Ausführung ein Backup des Projekts an und gibt am Ende einen Umstellungsbericht aus (Top-Level-Abhängigkeiten, transitive Abhängigkeiten, erkannte Kompatibilitätsprobleme). Zum Zurücksetzen wird laut Dokumentation csproj und packages.config aus dem Backup-Ordner zurückgeschrieben und in der Paket-Manager-Konsole update-package -reinstall ausgeführt.

Das heißt: Sie können es reversibel ausprobieren. Bei der Schätzung vor dem Start ist es am schnellsten, zunächst nur ein Projekt umzustellen und den Bericht zu lesen.

4.3 Auf den SDK-Stil umstellen

Der Leitfaden zum Vorbereiten des Portierens empfiehlt auch die Umstellung auf das SDK-Stil-Projektformat.

Das zahlt sich deutlich aus.

Was sich mit dem SDK-Stil ändert

  • Die csproj wird erheblich schlanker
  • Passt gut zu PackageReference
  • Multi-Targeting wird einfach
  • Lässt sich leichter auf CI/CD zentriert um dotnet build / dotnet test / dotnet publish ausrichten
  • Nähert sich der Konfiguration der modernen .NET-Seite an, wodurch der Diff in der späteren Phase kleiner wird

Umgekehrt gilt: Springt man mit alter csproj und altem NuGet-Management direkt zu modernem .NET, wird der Diff zu groß.

4.4 Abhängigkeiten zuerst aktualisieren

Auch das folgt dem offiziellen Leitfaden: Bringen Sie Abhängigkeiten auf die jeweils neueste verfügbare Version und, wo möglich, auf .NET-Standard-kompatible Versionen.

Warum das vorab erledigen

  • Sie finden früh heraus, ob „dieses Paket auf modernem .NET funktioniert“
  • Verhindert, dass alte Abhängigkeiten zu Rauschen werden
  • Erleichtert die Umstellung von Shared Libraries auf netstandard2.0
  • Lässt die spätere Migrationsarbeit sich auf „das Portieren des Codes“ konzentrieren

4.5 Auch die Voraussetzungen der offiziellen Tools prüfen

Stand März 2026 hat sich der Schwerpunkt von Microsofts Empfehlungen zu GitHub Copilot App Modernization verschoben. Statt sich nur auf die klassischen Migrationsassistenten zu verlassen, passt es besser zur Praxis, das Ganze als durchgängigen Unterstützungsablauf zu sehen, der Bewertung, Planung, Codekorrekturen und Validierung umfasst.

Allerdings setzt die aktuelle Dokumentation Visual Studio 2026 oder eine unterstützte Visual-Studio-2022-Version, GitHub Copilot und C#-Code voraus.

Warum diese Prüfung nötig ist

  • Sie ändert, was Sie von den offiziellen Tools erwarten können
  • Sie können die Annahmen des Teams zu IDE / Build-Agent / Erweiterungen aneinander ausrichten
  • Sie können die Entscheidung treffen, bei VB.NET-Lösungen nicht zu viel von der Automatisierung zu erwarten

Projekte mit VB.NET-Anteilen sind keine Seltenheit. Es lohnt sich daher, gleich zu Beginn zu prüfen, „wie weit einem das neueste offizielle Tooling tatsächlich hilft“.

5. Den Schwierigkeitsgrad je Projekttyp einschätzen

Migration wird gern pauschal als „von .NET Framework zu .NET“ verhandelt, ist in der Realität aber je Projekttyp ein eigenes Spiel.

5.1 Ein grobes Gefühl für den Schwierigkeitsgrad

Typ Schwierigkeitsgrad Wichtigste Themen
Klassenbibliothek Niedrig bis mittel API-Kompatibilität, Abhängigkeiten, Aufteilung der Ziel-Frameworks
Konsole / Batch / einige Windows-Dienste Niedrig bis mittel Verteilungsart, native Abhängigkeiten, Konfiguration
WinForms / WPF Mittel Bleibt Windows-exklusiv; Designer, Drittanbieter-UI, Umfeld von BinaryFormatter
ASP.NET MVC / Web API Mittel bis hoch Anwendungsmodell-Migration zu ASP.NET Core, Authentifizierung, Sitzung, Konfiguration, DI
ASP.NET Web Forms Hoch Großer Unterschied im Seitenmodell; UI-Schicht-Ersatz einplanen
WCF-Client Mittel Paketersatz, Contracts, Konfiguration
WCF-Server Hoch CoreWCF oder Redesign auf gRPC / HTTP-API
EF6 → EF Core gleichzeitig Hoch Der ORM ist ein anderes Tier, Verhaltensunterschiede, Migrationshistorie

5.2 Bei Klassenbibliotheken ist entscheidend, wie die „gemeinsame Grenze“ geschnitten wird

Klassenbibliotheken lassen sich vergleichsweise leicht umziehen. Das gilt allerdings nur, wenn die Bibliothek wirklich sauber als Bibliothek abgetrennt ist.

Bei folgenden Abhängigkeiten steigt der Schwierigkeitsgrad:

  • Berührung von System.Web
  • Direkter Zugriff auf HttpContext.Current
  • WPF-/WinForms-Typen in der öffentlichen API
  • Starke Abhängigkeit von Windows-APIs wie Registry, WMI, EventLog
  • Abhängigkeit von AppDomain oder Remoting

Eine hilfreiche Faustregel: Lässt sich reine Geschäftslogik herauslösen, ist es leicht; hat die Bibliothek das Anwendungsmodell mit verschluckt, ist es schwer.

5.3 WinForms / WPF lassen sich leicht migrieren, bleiben aber Windows-exklusiv

WinForms und WPF lassen sich zu .NET migrieren. Beide bleiben jedoch Windows-exklusive Frameworks.

Falsche Erwartungen sind hier gefährlich.

  • Was besser wird
    • Sie erhalten die moderne .NET-Runtime, die Sprache und den SDK-Stil
    • CI/CD und Paketverwaltung lassen sich zeitgemäß gestalten
    • Manche Leistungs- und Wartbarkeitsverbesserungen kommen mit
  • Was gleich bleibt
    • Es bleibt Windows-exklusiv
    • Kompatibilitätsprobleme mit UI-Steuerelementen und Entwurfszeit-Komponenten bleiben bestehen
    • ActiveX-/COM-/native-DLL-Probleme verschwinden nicht

Außerdem kann bei WinForms / WPF eine Prüfung der BinaryFormatter-Auswirkungen nötig sein. Besonders wenn benutzerdefinierte Typen in Clipboard, Drag & Drop, ResX oder Entwurfszeit-Serialisierung eine Rolle spielen, tritt das Problem gern zutage, sobald das Ziel auf .NET 9 oder höher angehoben wird.

5.4 ASP.NET Framework ist eine „Anwendungsmodell-Migration“, keine „Runtime-Migration“

Die Migration von ASP.NET Framework zu ASP.NET Core wird auch in Microsofts Leitfaden ausdrücklich als nicht trivial bezeichnet. Das liegt nicht nur daran, dass sich API-Namen ändern, sondern daran, dass die zugrunde liegende Architektur unterschiedlich ist.

Die Unterschiede zeigen sich vor allem hier:

  • Hosting-Modell
  • Middleware-Pipeline
  • Verarbeitungsmodell für Anfragen
  • Sitzung / Cache
  • Authentifizierung / Autorisierung
  • Konfiguration
  • Dependency Injection
  • Logging / Überwachung

Bei einer ASP.NET-Framework-Anwendung sollten Sie zuerst Folgendes prüfen:

  • Welche Routen / Endpunkte lassen sich zuerst umziehen
  • Lassen sich System.Web-Abhängigkeiten aus Shared Libraries entfernen
  • Wie werden Authentifizierung / Sitzung / Fehlerbehandlung / Logging angeglichen
  • Soll stufenweise migriert werden, ohne die Produktion anzuhalten

Besonders bei großen Anwendungen ist es realistischer, von vornherein von einer inkrementellen Migration auszugehen.

5.5 Bei Web Forms beginnt man mit „Zerlegung der Verantwortlichkeiten“, nicht mit „Migration der Assets“

Web Forms ist nicht dasselbe Anwendungsmodell wie ASP.NET Core. Für die Schätzung ist es deshalb sicherer, nicht davon auszugehen, dass sich die Bildschirm-Assets unverändert übernehmen lassen.

In der Praxis beginnt man meist mit dieser Zerlegung:

  • Bildschirmlogik von Geschäftslogik trennen
  • In Page / UserControl / ViewState eingebettete Verantwortlichkeiten aufbrechen
  • Geschäftslogik und Datenzugriff in Shared Libraries auslagern
  • Die UI mit einem anderen Modell neu aufbauen: Razor Pages / MVC / Blazor usw.

Mit anderen Worten: Bei Web-Forms-Projekten zählt eher, ob ein Plan zur Zerlegung der Verantwortlichkeiten existiert, als die Runtime-Migration selbst.

5.6 WCF-Client und WCF-Server getrennt betrachten

Hier sollten Sie nicht alles in einen Topf werfen.

WCF-Client

Für den WCF-Client gibt es unterstützte NuGet-Pakete für modernes .NET. Deshalb kann es vorkommen, dass es weniger aufwendig ist, als es aussieht, wenn Sie WCF nur aufrufen.

WCF-Server

Anders sieht es aus, wenn Sie WCF-Dienste hosten. Microsofts Leitfaden nennt im Wesentlichen zwei Modernisierungswege:

  • CoreWCF verwenden, um die Kompatibilität mit bestehenden Clients zu erhalten
  • Auf moderne RPC-/HTTP-basierte Ansätze wie gRPC umsteigen

Beachten Sie, dass CoreWCF nicht das gesamte WCF unverändert übernimmt, sondern eine Teilmenge ist. Es eignet sich gut, um die Kompatibilität mit bestehenden Clients zu erhalten, doch Codeänderungen und Tests sind eine Selbstverständlichkeit.

6. Technologien durchleuchten, die auf .NET nicht funktionieren oder leicht zu Problemen führen

Das sollten Sie unbedingt vor dem Start erledigen. Microsoft führt eine Liste von Technologien, die unter .NET Framework funktionierten, aber unter .NET 6+ nicht mehr verfügbar sind.

6.1 Technologien, die leicht zu Rotlichtern werden

Technologie Status unter .NET Wie damit umgehen
Erstellung von AppDomains, z. B. AppDomain.CreateDomain Nicht unterstützt Isolation über separate Prozesse / Container / AssemblyLoadContext denken
.NET Remoting Nicht unterstützt Redesign auf IPC, HTTP, gRPC, Sockets, Pipes
CAS / Security Transparency Als Sicherheitsgrenze nicht unterstützt In Betriebssystem-/Container-/Rechtetrennung denken
System.EnterpriseServices (COM+) Nicht unterstützt COM+-basierte Designs isolieren und ersetzen
Workflow Foundation Nicht unterstützt Separat schätzen, einschließlich Alternativen wie CoreWF
WCF-Server Nicht eingebaut wie zuvor verfügbar CoreWCF oder gRPC wählen
BinaryFormatter Wirft ab .NET 9 immer eine Ausnahme Serialisierer migrieren, ResX / Clipboard / Drag & Drop prüfen

6.2 AppDomain: „Manche APIs bleiben erhalten, aber die Erstellung ist eine andere Sache“

Der Bereich AppDomain ist etwas heikel. Ein Teil der API-Oberfläche bleibt auch unter .NET erhalten, aber das Vorgehen, eine neue AppDomain zur Isolation zu erstellen, wird nicht unterstützt.

Wurde AppDomain für folgende Zwecke verwendet, ist ein Redesign nötig:

  • Plugin-Isolation
  • Entladen von dynamisch geladenem Code
  • Isolation von teilweise vertrauenswürdigem Code
  • Temporäre Trennung von Ausführungsumgebungen

Vor der Migration sollten Sie nicht nur prüfen, ob das Wort AppDomain vorkommt, sondern wofür die AppDomain verwendet wurde.

6.3 Remoting ist „tiefer, als es aussieht“

Remoting selbst ist offensichtlich betroffen, aber auch asynchrone Delegate-Aufrufe wie BeginInvoke() / EndInvoke() können in den betroffenen Bereich fallen. Das ist zwar nicht Remoting selbst, wird aber auf modernem .NET nicht unterstützt und muss deshalb vor der Migration durchleuchtet werden.

Bei der Suche lohnt es sich daher, auch Folgendes im Blick zu behalten:

  • System.Runtime.Remoting
  • MarshalByRefObject
  • RealProxy
  • BeginInvoke( / EndInvoke(

6.4 BinaryFormatter tritt je nach Zielversion plötzlich in den Vordergrund

Je älter die Codebasis, desto eher wird BinaryFormatter „unbewusst“ verwendet.

  • Persistierte Daten
  • Caches
  • Sitzungsspeicherung
  • Plugin-Zustand
  • Clipboard / Drag & Drop
  • ResX
  • Umfeld des WinForms-/WPF-Designers

Ab .NET 9 enthält die Runtime keine Implementierung von BinaryFormatter mehr, und die API wirft stets PlatformNotSupportedException. Das heißt: Dies ist kein Thema, das man „später bedenkt“, sondern ein Prüfpunkt, sobald die Zielversion feststeht.

6.5 Suchbegriffe, die sich zuerst zu grep-en lohnen

Schon eine Suche über die gesamte Lösung mit den folgenden Begriffen verändert das Bild vor dem Start erheblich.

System.Web
HttpContext.Current
System.Runtime.Remoting
MarshalByRefObject
AppDomain
BinaryFormatter
ServiceHost
ChannelFactory
System.EnterpriseServices
Workflow
packages.config
web.config.install.xdt
install.ps1
DllImport
AxInterop
Microsoft.Office.Interop

Findet sich auch nur einer dieser Begriffe, bedeutet das nicht automatisch ein Ausschlusskriterium. Es ist eine Landkarte, um zu erkennen, welche Teile auf dem Standardweg migrieren können und welche zu einer separaten Spur werden.

Der tatsächliche Suchbefehl

Als Werkzeug eignen sich sowohl rg (ripgrep) als auch PowerShell.

# PowerShell. Durchsucht die gesamte Lösung gebündelt
Get-ChildItem -Recurse -Include *.cs,*.vb,*.config,*.csproj,*.vbproj |
    Select-String -Pattern 'BinaryFormatter|System\.Runtime\.Remoting|MarshalByRefObject|AppDomain\.CreateDomain' |
    Select-Object Path, LineNumber, Line
# ripgrep. Zum schnellen Überblick über die Trefferzahl
rg -n --stats "BinaryFormatter|System\.Runtime\.Remoting|AppDomain\.CreateDomain" --glob "*.cs" --glob "*.vb"

Was nach einem Treffer als Nächstes zu tun ist

Die Suche ist der Einstieg, die eigentliche Arbeit ist die anschließende Bewertung. Für jeden Begriff steht fest, wo als Nächstes nachzusehen ist.

Gefundener Begriff Was als Nächstes zu prüfen ist Wohin es führt
System.Web / HttpContext.Current Lässt es sich aus der Shared Library nach außen verlagern? Lässt sich die aufrufende Seite auf DTOs umstellen? Mit der Strategie aus 8.5 entfernen
System.Runtime.Remoting / MarshalByRefObject / BeginInvoke Wozu diente der Remote-Aufruf? Zwischen Prozessen, zwischen Maschinen oder nur ein einfacher asynchroner Aufruf? Redesign auf IPC, HTTP, gRPC, Task-basiert
AppDomain Wird nur der Typname verwendet, oder wird mit CreateDomain isoliert? Bei Isolationszweck separater Prozess oder AssemblyLoadContext (6.2)
BinaryFormatter Müssen geschriebene Daten später wieder gelesen werden? Wird es indirekt über ResX oder Clipboard genutzt? Auf einen anderen Serialisierer migrieren und einen Umlesungsplan für Bestandsdaten aufstellen (6.4)
ServiceHost / ChannelFactory Host-Seite oder Client-Seite? Getrennt bewerten wie in 5.6
packages.config / install.ps1 / web.config.install.xdt Was wurde bei der Installation umgeschrieben? Fallstrick aus 4.2. Konfiguration explizit neu übernehmen
DllImport / AxInterop / Microsoft.Office.Interop Bitness-Annahmen und der zur Laufzeit benötigte Dateisatz Weiter zur Bitness-Prüfung in 9.4

Ist das erledigt, haben Sie nicht die Frage „lässt es sich migrieren“, sondern eine Liste „was auf dem Standardweg läuft und was eine separate Schätzung braucht“. Genau diese Form der Liste wollen Sie vor dem Start haben.

7. Entscheiden, wie viel Windows-exklusive Abhängigkeit Sie akzeptieren

Ein häufiges Missverständnis bei Migrationen lautet: „Sobald wir auf .NET sind, sind wir plattformübergreifend.“ Diese Magie gibt es nicht. Ist die Anwendung tief mit Windows verwoben, bleibt sie auch nach der Migration ganz normal Windows-exklusiv.

7.1 Windows-exklusiv zu migrieren ist durchaus realistisch

Microsoft bietet das Windows Compatibility Pack, mit dem sich zahlreiche Windows-orientierte APIs — Registry, WMI, EventLog, Windows-Dienste, Directory Services und mehr — aus modernem .NET heraus nutzen lassen.

Diese Existenz zählt in der Praxis viel.

  • Wir wollen zuerst zu modernem .NET wechseln
  • Aber wir verlassen Windows vorerst nicht
  • Also wollen wir die Windows-API-Abhängigkeiten vorerst akzeptieren

Für Teams in dieser Situation ist das eine starke Option.

Das erste Ziel einer Migration muss nicht zwingend Plattformübergreifendheit sein.

7.2 Windows-exklusive APIs sind aber auch „Schulden, die sich später rächen“

Nur weil es das Windows Compatibility Pack gibt, ist nicht automatisch alles unbedenklich.

  • Sie wollen in Linux-Containern laufen
  • Sie wollen unter Kubernetes betreiben
  • Sie wollen, dass macOS-/Linux-Entwickler denselben Build ausführen
  • Sie wollen künftig Windows-VMs in der Cloud reduzieren

Haben Sie solche Ziele, ist es besser, die Windows-API-Abhängigkeiten schon jetzt sichtbar zu machen.

7.3 System.Drawing.Common wird besonders leicht missverstanden

System.Drawing.Common ist ab .NET 6 eine Windows-exklusive Bibliothek. Wenn Sie Code haben, der es für Bildverarbeitung oder Textausgabe nutzt, müssen Sie zuerst entscheiden, welchen Weg Sie gehen.

  • Weiter unter Windows betreiben?
  • Oder künftig auch unter Linux / macOS laufen lassen?

Im ersten Fall kann es in Ordnung sein, es vorerst unverändert zu lassen. Im zweiten Fall muss ein Ersatz — SkiaSharp, ImageSharp usw. — von Anfang an in den Migrationsplan aufgenommen werden.

7.4 Typische Anzeichen für Windows-Bindung

Bei Verweisen oder APIs wie den folgenden ist es sicherer, mit der Annahme zu schätzen, „zumindest zunächst Windows-exklusiv zu migrieren“.

  • Microsoft.Win32.Registry
  • System.Management
  • System.Diagnostics.EventLog
  • System.ServiceProcess
  • System.DirectoryServices
  • System.Drawing
  • DllImport / P/Invoke
  • COM-Verweise
  • AxInterop.*
  • Microsoft.Office.Interop.*

8. Wie Sie Shared Libraries herauslösen, verändert den Schwierigkeitsgrad

Bei größeren Lösungen ist es keine Übertreibung zu sagen: Der Erfolg der Migration entscheidet sich daran, wie die Shared Libraries geschnitten werden.

8.1 Zuerst klassifizieren

Bibliotheken lassen sich am leichtesten ordnen, wenn man sie grob in drei Arten einteilt.

  1. Reine Geschäftslogik / Domänenlogik
  2. Mittlere Schicht mit leichter Abhängigkeit vom Anwendungsmodell
  3. Schicht, die eng an UI / Web / Windows-APIs gekoppelt ist

Von diesen sollte Art 1 als Erstes migriert werden.

  • Berechnungen
  • Regelauswertung
  • DTOs / Contracts
  • Domänendienste
  • Einfache Datenumwandlungen

Lässt sich das sauber herauslösen, sinkt der Schwierigkeitsgrad deutlich.

8.2 netstandard2.0 ist auch heute noch eine gültige Brücke

Nach Microsofts Leitlinie gilt für eine Shared Library, die auch mit der .NET-Framework-Seite koexistieren muss, grundsätzlich zuerst .NET Standard 2.0 in Betracht zu ziehen.

Zwei Punkte sind hier wichtig.

  • .NET Framework unterstützt .NET Standard 2.1 nicht
  • Soll eine Shared Library sowohl aus alt als auch aus neu referenziert werden, ist 2.0 meist die praktikable Lösung

8.3 Was sich mit netstandard2.0 ändert

Ansatz Was sich ändert Geeignet für Zu beachten
Umstellung auf netstandard2.0 Leicht sowohl von alt als auch von neu zu referenzieren Reine Geschäftslogik, gemeinsame Contracts, Utilities Anwendungsmodell-spezifische APIs können hier nicht liegen
Multi-Targeting (z. B. net48;net10.0) Gemeinsamer Code bleibt erhalten, Unterschiede je Umgebung lassen sich abbilden Bibliotheken mit leichten Umgebungsunterschieden Mehr bedingte Kompilierung und Build-Verwaltung
Direkt nur noch net10.0 Langfristig am saubersten Neue Schichten ohne Koexistenzbedarf von alt und neu Kann nicht mehr aus .NET Framework referenziert werden

8.4 Der Kompatibilitätsmodus ist kein Allheilmittel

.NET Standard 2.0 verfügt über einen Kompatibilitätsmodus, der das Referenzieren von .NET-Framework-Bibliotheken erlaubt. Das ist jedoch keine Magie, die alles transparent funktionieren lässt.

Bibliotheken, die zum Beispiel anwendungsmodellspezifische APIs wie WPF voraussetzen, sind ganz normal schwierig. Mit anderen Worten: Auch wenn man „Shared Library“ sagt, ist es wichtig, sich wirklich auf die Verantwortlichkeiten zu beschränken, die sich tatsächlich teilen lassen.

8.5 Bei ASP.NET-Bibliotheken entscheidet, ob sich System.Web entfernen lässt

Migrieren Sie ASP.NET Framework stufenweise, ist es ziemlich schmerzhaft, wenn Shared Libraries direkt an HttpContext.Current oder System.Web hängen.

Die grundlegenden Strategien dafür sind eine der folgenden:

  • Die System.Web-Abhängigkeit hinter eine Schnittstelle drängen
  • Den Code so ändern, dass von HttpContext stammende Informationen als DTOs entgegengenommen werden
  • Während der Übergangszeit einen Adapter verwenden
  • Geht auch das nicht, schrittweise mit Multi-Targeting entfernen

8.6 Bibliotheken leaf-first anheben

Der Leitfaden zur inkrementellen ASP.NET-Migration gibt ausdrücklich vor, unterstützende Bibliotheken postorder depth-first, also von den Blättern aus, anzuheben.

Das ist nicht nur im Web-Umfeld, sondern auch bei allgemeinen Lösungen ziemlich wirksam.

  • Weil die Abhängigkeiten zuerst angehoben werden, wird der Überblick über die oberen Schichten besser
  • Kompatibilitätsprobleme lassen sich leichter eingrenzen
  • Tests je Bibliothek werden einfacher

9. NuGet / externe Abhängigkeiten / Drittanbieter-Komponenten inventarisieren

Wird das nachlässig erledigt, erleben Sie in der zweiten Hälfte der Migration die schmerzhaftesten Überraschungen.

9.1 Abhängigkeiten lassen sich am leichtesten in 4 Kategorien ordnen

  1. Öffentliche NuGet-Pakete
  2. Interne private Pakete / interne Bibliotheken
  3. Lokale DLL-Verweise
  4. COM / ActiveX / native DLLs / SDKs

Nur Kategorie 1 zu betrachten reicht nicht. Wirklich gefährlich sind 3 und 4.

9.2 Was pro Abhängigkeit zu prüfen ist

Prüfen Sie für jede Abhängigkeit mindestens Folgendes:

  • Zielt sie auf modernes .NET ab?
  • Unterstützt sie PackageReference?
  • Ist sie mit dem SDK-Stil unproblematisch?
  • Gibt es Einschränkungen bei x86 / x64 / ARM64?
  • Hängt sie von Entwurfszeit-Tools oder Visual-Studio-Erweiterungen ab?
  • Setzt sie Installationsskripte / Konfigurationstransformationen voraus?
  • Wird sie noch unterstützt?

9.3 Drittanbieter-UI / Reporting / Entwurfszeit-Komponenten separat einschätzen

Bei Migrationen von WinForms / WPF / ASP.NET macht sich das hier deutlich bemerkbar.

  • Grids
  • Reporting-Engines
  • PDF-Ausgabe-Komponenten
  • Diagramm-Komponenten
  • Designer-integrierte UI-Bibliotheken
  • ActiveX-Wrapper

Hier geht es nicht nur um die Runtime, sondern auch um Entwurfszeit-Unterstützung. Prüft Ihre Migrationsschätzung nur „lässt es sich kompilieren“, übersehen Sie das ganz normal.

9.4 Native DLLs und Bitness immer prüfen

Auch wenn etwas zur Zeit von .NET Framework so aussah, als liefe es unter AnyCPU, kann in Wirklichkeit eine Abhängigkeit von Folgendem bestehen:

  • Auf x86 festgelegtes COM
  • Nur 32-Bit-fähiges ActiveX
  • Eine bestimmte Version der VC++-Runtime
  • Signierte native DLLs

Das sind keine Probleme, die durch die Modernisierung auf modernes .NET neu entstehen — es sind von Anfang an bestehende Einschränkungen, die nur sichtbar werden. Genau deshalb lohnt es sich, sie vor der Migration sichtbar zu machen.

10. EF6, Serialisierer und die Datenschicht als separate Probleme behandeln

Die Runtime-Migration und das Redesign von Datenzugriff und Serialisierung funktionieren besser, wenn man sie möglichst als separate Probleme behandelt.

10.1 EF6 → EF Core ist kein direktes Upgrade

Auch Microsofts EF-Leitfaden besagt, dass EF Core eine vollständige Neuentwicklung von EF6 ist und es keinen direkten Upgrade-Pfad gibt.

Für Anwendungen, die EF6 verwenden, ist deshalb diese Reihenfolge realistisch:

  1. Zuerst zu modernem .NET wechseln
  2. EF6 bei Bedarf beibehalten und die Anwendung so betreiben
  3. Danach als separates Projekt zu EF Core migrieren

Kombinieren Sie die Runtime-Migration nicht mit der ORM-Migration. Allein das senkt den Schwierigkeitsgrad erheblich.

10.2 Was sich ändert, wenn Sie EF6 behalten

  • Vorteile
    • Der Diff der Datenzugriffsschicht lässt sich aufschieben
    • Sie können sich auf die Migration von Geschäftslogik und Anwendungsmodell konzentrieren
    • „Verhaltensunterschiede von EF Core“ mischen sich nicht ein
  • Zu beachten
    • Für Neuentwicklungen ist EF Core die erste Wahl
    • EF6-Designer-/EDMX-Nutzung unterliegt eigenen Einschränkungen

10.3 Bei EDMX-basiertem EF6 auch die „Entwurfszeit“ betrachten

Die EF6-Dokumentation besagt, dass der EF Designer in .NET-/.NET-Standard-Projekten oder SDK-Stil-.NET-Framework-Projekten nicht direkt unterstützt wird.

Bei EDMX-basierten Anwendungen müssen Sie diese drei Punkte getrennt betrachten:

  • Läuft es zur Laufzeit?
  • Lässt sich der Designer nutzen?
  • Wie wird mit dem generierten Code umgegangen?

Nutzen Sie EDMX intensiv, ist es sicherer, das von Anfang an in die Schätzung aufzunehmen.

10.4 BinaryFormatter und eigene Serialisierung werden leicht zu „versteckten Abhängigkeiten“

Serialisierer werden bei einer reinen Codesuche leicht übersehen.

  • Persistenzformate
  • Messaging
  • Caches
  • Alte WCF-/SOAP-Contracts
  • ResX
  • Clipboard / Drag & Drop

Hier spielt auch Datenkompatibilität eine Rolle. Das heißt, Sie müssen nicht nur prüfen, „lässt es sich bauen“, sondern auch, ob sich alte Daten noch lesen lassen.

11. Konfiguration, Verteilung, Betrieb und CI/CD ebenfalls in den Migrationsumfang einbeziehen

Das Migrationsziel ist nicht nur der Quellcode.

11.1 Konfigurationsdateien

Auf der .NET-Framework-Seite steckt oft einiges in app.config / web.config.

  • Connection Strings
  • Benutzerdefinierte Konfigurationsabschnitte
  • WCF-Endpunktkonfiguration
  • Binding Redirects
  • Diagnostics
  • Diverse ASP.NET-Einstellungen
  • Ergebnisse von Transformationen bei der Paketinstallation

Auf der modernen .NET-Seite ändern sich mancherorts Art und Ladepfad der Konfiguration. Deshalb ist „Konfigurationsdateien später“ gefährlich.

Das Erste, was zu tun ist, ist die Bestandsaufnahme der Konfiguration.

  • Was steht in den Konfigurationsdateien
  • Was ist beim Anwendungsstart zwingend erforderlich
  • Was sind Umgebungsunterschiede
  • Was wurde automatisch von NuGet oder Installern eingefügt

11.2 Verteilungsart

Prüfen Sie auch die Verteilungsform vor dem Start.

  • Läuft es unter IIS?
  • Ist es ein Windows-Dienst?
  • Ein geplanter Task?
  • ClickOnce / MSI / ein eigener Installer?
  • Wird ein On-Premises-Server vorausgesetzt?
  • Passt Self-Contained oder Framework-Dependent besser?

Migriert die ausführbare Datei selbst erfolgreich, geraten Sie am Ende trotzdem ins Stocken, wenn Verteilung und Startmechanismus weiterhin die alte Welt voraussetzen.

11.3 Logging, Überwachung und Betriebsabläufe

Auch der Betrieb wird leicht übersehen.

  • Wird das Windows Event Log vorausgesetzt?
  • Werden Performance Counter beobachtet?
  • Erfolgt WMI-basierte Überwachung?
  • Sind Dienstkonten und Berechtigungen fest vorgegeben?
  • Setzt die Protokollausgabe lokale Dateien voraus?

„Der Code läuft nach der Migration, aber der Betrieb funktioniert nicht“ kommt ganz normal vor.

11.4 CI/CD und Build-Agenten

Prüfen Sie vor der Migration auch Folgendes:

  • Lässt sich das benötigte .NET-SDK auf den Build-Agenten installieren?
  • Was geschieht mit Pipelines, die nuget.exe / msbuild.exe voraussetzen?
  • Soll auf die dotnet-CLI umgestellt werden?
  • Wie werden Test-, Coverage- und Publish-Jobs aktualisiert?
  • Setzen interne Vorlagen oder wiederverwendbare Pipelines noch die alten Formate voraus?

„Auf dem lokalen Rechner läuft es, aber die CI stirbt“ ist ein Migrationsklassiker.

12. Ein realistisches Vorgehen für die Migration

Berücksichtigt man alle bisherigen Punkte, läuft ein realistisches Vorgehen meist auf ungefähr Folgendes hinaus.

12.1 Zuerst die aktuelle Framework-Seite in Ordnung bringen

  1. Auf .NET Framework 4.7.2 oder höher wechseln, idealerweise 4.8.1
  2. Abhängigkeiten aktualisieren
  3. packages.config überprüfen
  4. So weit wie möglich auf PackageReference und SDK-Stil umstellen
  5. Bestätigen, dass die aktuelle Anwendung in diesem Zustand einwandfrei funktioniert

Allein das reduziert den Diff in der späteren Phase erheblich.

12.2 Shared Libraries zuerst retten

Als Nächstes stellen Sie Geschäftslogik und gemeinsame Contracts auf netstandard2.0 oder Multi-Targeting um. Die Reihenfolge des Anhebens folgt grundsätzlich dem Prinzip leaf-first.

12.3 Für die Anwendung selbst die Strategie je Anwendungsmodell variieren

  • Klassenbibliothek / Konsole / einige Dienste Lässt sich vergleichsweise geradlinig vorantreiben
  • WinForms / WPF Modernisieren, während Windows-exklusiv bleibt
  • ASP.NET MVC / Web API Bei kleinem Umfang alles auf einmal, bei großem stufenweise
  • Web Forms Bildschirm-Ersatz einplanen, gemeinsame Logik zuerst auslagern
  • WCF-Server Zuerst entscheiden: bei CoreWCF bleiben oder auf gRPC umgestalten

12.4 An „nicht alles auf einmal“ festhalten

Besonders vermeiden sollten Sie diese Kombinationen:

  • Runtime-Migration + vollständiger ORM-Austausch
  • Runtime-Migration + Änderung der Authentifizierungsinfrastruktur
  • Runtime-Migration + vollständige Cloud-Migration
  • Runtime-Migration + Änderung der Überwachungsinfrastruktur
  • Runtime-Migration + Erneuerung des UI-Frameworks

Auch wenn am Ende alles nötig ist, funktioniert es meist besser, es nicht im selben Sprint zu stapeln.

12.5 Erst Tests und Baselines aufnehmen, dann loslegen

Mindestens so viel sollten Sie vorbereitet haben, bevor Sie loslegen:

  • Unit-Tests
  • Integrationstests für die wichtigsten Geschäftsabläufe
  • Snapshot-artige Überprüfung repräsentativer Bildschirme / APIs
  • Eine Leistungs-Baseline
  • Eine Methode, die wichtigsten Logs zu prüfen
  • Ein Rollback-Verfahren

In einem Zustand vorzugehen, in dem sich nach der Migration nicht feststellen lässt, „was kaputtgegangen ist“, ist ziemlich gefährlich.

13. Checkliste vor dem Start

Hier in einer Form, die sich direkt ins Projektmanagement einfügen lässt.

13.1 Ausrichtung

  • Sie können in einem Satz sagen, warum migriert wird
  • Der Zielpunkt ist entschieden: Windows-exklusives modernes .NET oder künftige Plattformübergreifendheit
  • Die Ziel-.NET-Version ist festgelegt
  • Was nicht im aktuellen Umfang enthalten ist (EF-Core-Umstellung, Auth-Erneuerung, vollständige Cloud-Migration usw.) ist festgelegt

13.2 Vorbereitung der aktuellen .NET-Framework-Seite

  • Auf .NET Framework 4.7.2 oder höher gewechselt, idealerweise 4.8.1
  • Abhängigkeiten möglichst aktuell gehalten
  • Das Vorhandensein von packages.config durchleuchtet
  • Die Machbarkeit der Umstellung auf PackageReference geprüft
  • Die Machbarkeit der Umstellung auf den SDK-Stil geprüft
  • Die aktuelle Anwendung baut, startet und besteht die Tests in diesem Zustand

13.3 Anwendungstyp und Technologiewahl

  • Den Schwierigkeitsgrad nach Typ getrennt: Klassenbibliothek / Desktop / Web / WCF usw.
  • Verstanden, dass WinForms / WPF Windows-exklusiv bleiben
  • Verstanden, dass ASP.NET Framework eine Anwendungsmodell-Migration zu ASP.NET Core bedeutet
  • Den UI-Schicht-Ersatz für Web Forms in die Schätzung aufgenommen
  • WCF-Client und WCF-Server getrennt bewertet

13.4 Nicht unterstützte Technologien / kritische APIs

  • AppDomain-Abhängigkeiten durchleuchtet
  • Remoting / MarshalByRefObject / BeginInvoke / EndInvoke durchleuchtet
  • CAS / Security Transparency / COM+ / WF durchleuchtet
  • BinaryFormatter-Abhängigkeiten durchleuchtet
  • System.Web-Abhängigkeiten durchleuchtet

13.5 Windows-exklusive Abhängigkeiten

  • Die Nutzung von Registry, WMI, EventLog, Windows-Diensten und Directory Services durchleuchtet
  • Die Nutzung von System.Drawing.Common durchleuchtet
  • COM / ActiveX / Office Interop / P/Invoke / native DLLs durchleuchtet
  • Einschränkungen bei x86 / x64 / ARM64 geprüft

13.6 Shared Library und Datenzugriff

  • Shared Libraries in Geschäftslogik / eng ans Anwendungsmodell gekoppelte Schichten eingeteilt
  • Durchleuchtet, was sich auf netstandard2.0 umstellen lässt
  • Bibliotheken durchleuchtet, die Multi-Targeting benötigen
  • Entschieden, ob die Runtime zuerst umziehen kann, während EF6 erhalten bleibt
  • EDMX-/Designer-Abhängigkeiten geprüft

13.7 Betrieb und Build

  • Eine Bestandsaufnahme der Konfigurationsdateien durchgeführt
  • Die Verteilungsart geprüft (IIS / Dienst / MSI / ClickOnce usw.)
  • Annahmen zu Logging / Überwachung / Berechtigungen / Ausführungskonto geprüft
  • Geprüft, ob CI/CD und Build-Agenten aktualisiert werden müssen
  • Ein Rollback-Verfahren erstellt

14. Zusammenfassung

Bei der Migration von .NET Framework zu .NET zählt weniger „mit welchem Befehl migriert wird“ als vielmehr vor dem Start zu erkennen, was unverändert übernommen werden kann und was ein separates Problem ist.

Auf das Wesentliche verdichtet sind das diese sechs Punkte:

  • Vor der Migration die .NET-Framework-Seite aufräumen
  • Den Schwierigkeitsgrad je Anwendungsmodell trennen
  • Nicht nutzbare Technologien zuerst durchleuchten
  • Entscheiden, wie viel Windows-exklusive Abhängigkeit akzeptiert wird
  • Entscheiden, wie die Shared Libraries geschnitten werden
  • ORM-, Auth- und Cloud-Migration nicht gleichzeitig auftürmen

In der ersten Woche einer Migration verändert sich die Genauigkeit der Schätzung erheblich. Umgekehrt lässt sich, wenn Sie in dieser Woche die Themen sortieren können, die zweite Hälfte ziemlich nah an gewöhnliche Entwicklungsarbeit heranführen.

„Versuchen wir erst einmal, auf net10.0 umzustellen“ ist als Erkundung nicht schlecht. Als Produktivmigration gilt jedoch: Davor gibt es Dinge, die zu prüfen sind. Genau das hat dieser Artikel geordnet.

15. Referenzen

Aktuelle Artikel mit denselben Schlagwörtern führen zu verwandten Themen weiter.

Diese Seiten ordnen den Artikel in einen größeren Leistungs- und Entscheidungskontext ein.

Dieser Artikel ist direkt mit den folgenden Leistungen verbunden.

Technische Beratung und Design-Review

Wenn Sie vor dem Start den Migrationsumfang, die Aufteilung einer stufenweisen Migration und das Ausmaß der akzeptierten Windows-Abhängigkeit klären wollen, lässt sich dieses Thema gut als technische Beratung / Design-Review angehen.

Häufige Fragen

Fragen, die in Beratungen zu diesem Artikelthema häufig gestellt werden.

Was sollte ich vor der Migration von .NET Framework zu .NET zuerst tun?
Bevor Sie mit der Umsetzung beginnen, räumen Sie zuerst die .NET-Framework-Seite auf. Auch Microsofts offizieller Leitfaden empfiehlt, vor dem Portieren auf .NET Framework 4.7.2 oder höher (in der Praxis nach Möglichkeit 4.8.1) zu wechseln, packages.config auf PackageReference umzustellen, zum SDK-Stil-Projektformat zu wechseln und die Abhängigkeiten auf möglichst aktuelle Versionen zu bringen. Erledigen Sie das vorab, verringert sich der Diff der späteren Modernisierung auf .NET erheblich, und es lässt sich leichter unterscheiden, ob ein Kompatibilitätsproblem an der Alterung des Frameworks oder an der Umstellung auf .NET liegt. Ebenso gehört die Bestandsaufnahme nicht unterstützter Technologien wie AppDomain, Remoting und BinaryFormatter vor den Start.
Kann die Entscheidung fallen, bei .NET Framework zu bleiben?
Ja, das ist ganz normal möglich. .NET Framework 4.8.1 wird weiterhin unterstützt, solange es auf einem unterstützten Windows läuft — es ist also nicht so, dass sofort Gefahr droht, wenn nicht augenblicklich alles auf modernes .NET umgestellt wird. Bei Bedingungen wie einem großen Bestand an Web-Forms-Bildschirmen, der Notwendigkeit, die WCF-Serverkompatibilität streng einzuhalten, tiefen Abhängigkeiten von Workflow Foundation oder COM+ oder nicht unterstützten Drittanbieter-Designer-Komponenten ist es sinnvoll, vorerst auf 4.8.1 zu setzen, stabil weiterzubetreiben und die Ablösung auf einer separaten Schiene zu planen. Allerdings bleiben Einschränkungen bestehen: Sie kommen nicht aus der Windows-Bindung heraus, und Sie profitieren kaum von den Leistungs- und Sprachverbesserungen des neueren .NET.
Welche Technologien lassen sich nicht zu .NET migrieren oder führen leicht zu Problemen?
Die Erstellung von AppDomains, .NET Remoting, CAS (Code Access Security), COM+ (System.EnterpriseServices) und Workflow Foundation werden von modernem .NET nicht unterstützt — das sind Rotlichter, die ein Redesign erfordern. WCF-Server laufen nicht ohne Weiteres eingebaut weiter; Sie müssen sich zwischen CoreWCF oder einem Redesign auf gRPC / HTTP-API entscheiden. BinaryFormatter enthält ab .NET 9 keine Implementierung mehr und wirft stets eine Ausnahme, weshalb persistierte Daten, ResX sowie Clipboard / Drag & Drop geprüft werden müssen. Weitere Punkte, die trotz erfolgreichem Build zur Laufzeit gern ausfallen, sind die install.ps1- / XDT-Transformationen von packages.config, native DLLs, COM / ActiveX und x86-Annahmen.
Wird eine WinForms- oder WPF-Anwendung durch die Migration zu .NET plattformübergreifend?
Nein. WinForms und WPF bleiben auch nach der Migration zu .NET Windows-exklusive Frameworks. Die Migration bringt Vorteile wie die moderne .NET-Runtime, Sprachfunktionen, den SDK-Stil und eine bessere Kompatibilität mit CI/CD — sie macht die Anwendung aber nicht Linux-container-tauglich. Wenn Sie künftig Linux / Container anstreben, müssen Sie Windows-gebundene APIs wie System.Drawing.Common, die Registry, WMI, EventLog, Windows-Dienste, COM und Office Interop frühzeitig inventarisieren. Bleiben Sie hingegen bewusst bei Windows, ist es ein realistischer Weg, zunächst mit dem Windows Compatibility Pack nur die Runtime zu modernisieren.

Autorenprofil

Profilseite des Artikelautors.

Go Komura

Geschäftsführer von KomuraSoft LLC

Spezialisiert auf Windows-Softwareentwicklung, technische Beratung und Fehleranalyse, insbesondere bei bestehenden Systemen und schwer reproduzierbaren Störungen.

Zurück zum Blog