Am 10. November 2026 endet der Support für .NET 8 LTS. Der Support für .NET 9 endete bereits am 12. Mai 2026. Nach dem jeweiligen Termin gibt es keine regulären Sicherheits- und Wartungsupdates mehr, weshalb Entwicklungs- und DevOps-Teams neben dem Anwendungscode auch Build-Agenten, Container, Hosting-Komponenten und Rollback-Verfahren berücksichtigen müssen.
Eine .NET-Migration ist in erster Linie eine Produktionsänderung. Ein geändertes Target Framework reicht nicht: Erst reproduzierbare Builds, vergleichbare Messwerte und eine ausgeführte Rollback-Probe zeigen, ob der Wechsel freigegeben werden kann. Das Runbook trennt diese Arbeiten in acht prüfbare Schritte.
Was umfasst die Migration von .NET 8 auf .NET 10?
Der Wechsel aktualisiert das Target Framework sowie SDK, Runtime und sämtliche Build- und Deployment-Pfade auf die neue LTS-Version. Tests vergleichen das Verhalten mit einer dokumentierten .NET-8-Baseline. Telemetrie und eine ausgeführte Rollback-Probe zeigen vor der Freigabe, ob der neue Release produktionsfähig ist.
.NET 10 LTS wird planmäßig bis zum 14. November 2028 unterstützt. Der konkrete Patch-Stand ändert sich mit jedem Servicing Release und wird deshalb erst zum Migrationszeitpunkt festgelegt. Nach dem Supportende von .NET 8 lässt sich die Runtime nicht mehr auf einen vom Hersteller unterstützten Patch-Stand bringen.
Bevor das Team Änderungen plant, braucht es deshalb eine vollständige Liste aller Anwendungen und Laufzeitumgebungen.
Schritt 1: Anwendungen, Runtimes und Deployments inventarisieren
Repositories allein zeigen nicht, welche Runtime tatsächlich in Produktion läuft. Projektdateien, Publish-Profile und Pipeline-Definitionen liefern die Target Frameworks, Runtime Identifier und verwendeten SDK-Versionen. Auf Servern und Build-Agenten ergänzen dotnet --list-sdks sowie dotnet --list-runtimes den Befund.
| Inventarfeld | Zu erfassende Angaben |
|---|---|
| Anwendung | ASP.NET-Core-Dienst, API, Desktop-Anwendung, Hintergrunddienst oder Bibliothek |
| Bereitstellung | Framework-dependent, self-contained, Runtime Identifier, Trimming oder Single-File-Publishing |
| Hosting | Container, IIS, Windows-Dienst, Azure-Dienst oder Linux-System |
| Steuerung | Verantwortliche Person, Kritikalität, Wartungsfenster und Rollback-Vorgabe |
Gemeinsam verwendete Bibliotheken erhalten eigene Einträge, weil eine Änderung mehrere Anwendungen betreffen kann. Aus diesem Inventar entsteht im nächsten Schritt eine reproduzierbare .NET-8-Baseline.
Schritt 2: Auf den letzten unterstützten .NET-8-Patch aktualisieren
Ein veralteter Patch-Stand verfälscht den Vergleich mit .NET 10. Vor Beginn der eigentlichen Migration werden die Anwendung und ihre Produktions-Runtime deshalb auf den zu diesem Zeitpunkt neuesten unterstützten .NET-8-Patch gebracht. Die Pipeline protokolliert die verwendete Version mit dotnet --info.
Runtime-Patching und Framework-Migration bleiben getrennte Änderungen. Nach dem Patch zeichnet die Pipeline eine Baseline mit einem festgelegten Datenbestand und Lastprofil auf:
- Build-Status und Testergebnisse
- Latenz und Durchsatz unter definierter Last
- Arbeitsspeicher und Laufzeit der Garbage Collection
- CPU-Auslastung und Startzeit
- Fehlerrate und charakteristische Log-Ereignisse
Erst eine fehlerfrei baubare und auslieferbare .NET-8-Version eignet sich als Vergleichsbasis. Anschließend wird dieselbe SDK-Version auf Entwicklungsrechnern und Build-Agenten festgelegt.
Schritt 3: Das .NET-SDK mit global.json festlegen
Lokale Rechner und Build-Agenten liefern sonst unterschiedliche Ergebnisse, sobald mehrere SDK-Linien installiert sind. Eine global.json im Repository legt die freigegebene .NET-10-SDK-Linie fest.
{
"sdk": {
"version": "10.0.100",
"rollForward": "latestPatch",
"allowPrerelease": false
}
}
Die Versionsnummer ist ein Beispiel und wird durch die im Team freigegebene SDK-Linie ersetzt. latestPatch wählt den neuesten installierten Patch innerhalb derselben Feature-Band. Fehlt eine passende Version, bricht der Build ab, statt unbemerkt auf eine andere Feature-Band zu wechseln.
Die CI speichert zusätzlich dotnet --info als Build-Artefakt. Mit dieser festen Toolchain lassen sich anschließend Paket- und API-Probleme getrennt untersuchen.
Schritt 4: NuGet-Abhängigkeiten und inkompatible APIs prüfen
Eine erfolgreiche Kompilierung belegt noch keine Laufzeitkompatibilität. dotnet list package --outdated zeigt veraltete direkte Abhängigkeiten. dotnet list package --vulnerable --include-transitive erfasst bekannte Schwachstellen einschließlich transitiver Pakete.
Für jedes Paket zählt, welches Asset NuGet für net10.0 auswählt. Ein Paket für netstandard2.0 lässt sich grundsätzlich referenzieren, garantiert aber weder korrektes Laufzeitverhalten noch die Kompatibilität nativer Abhängigkeiten. Release-Hinweise und offene Inkompatibilitäten gehören deshalb in die Paketprüfung.
Nicht mehr benötigte Abhängigkeiten entfallen vor dem Framework-Wechsel. Für aufgegebene Pakete braucht das Team einen gepflegten Ersatz, bevor die eigentliche Migrations-Branch beginnt.
Schritt 5: Die Migration in einer eigenen Branch vorbereiten
Die reguläre Feature-Entwicklung läuft weiter, während die Umstellung geprüft wird. Eine Branch wie migration/dotnet10 trennt beide Änderungsarten. Framework und Pakete, Anwendungscode, Tests sowie Infrastruktur erhalten getrennte Commits, damit Reviews die Ursache einer Regression erkennen können.
Der .NET-8-Releasepfad bleibt verfügbar, bis alle Release-Gates erfüllt sind. Git-Workflows, Debugging und Refactoring behandelt auch die Visual Studio 2022 Grundlagen-Schulung, falls das Team diese Arbeitsweise vor der Migration vereinheitlichen möchte.
Nach der Branch-Trennung kann der Plattformwechsel beginnen, ohne gleichzeitig sprachliche Modernisierungen einzubauen.
Schritt 6: Zuerst net10.0, danach C# 14
Neue Sprachfeatures erschweren die Fehlersuche, wenn sie im selben Pull Request wie der Plattformwechsel landen. Der erste Pull Request ändert die Target Frameworks auf net10.0, stellt Pakete wieder her und behebt Build-Fehler, ohne das beabsichtigte Verhalten umzuschreiben.
Alle Build-Konfigurationen und Unit-Tests laufen nach jedem Änderungssatz. Erst nach erfolgreicher Runtime-Migration folgen bei Bedarf C#-14-Funktionen wie Extension Members, feldgestützte Properties, nullbedingte Zuweisungen und zusätzliche Konvertierungen für Span<T>. Ein getrennter Pull Request zeigt, ob eine Abweichung aus der Plattformmigration oder dem Refactoring stammt.
Klassendesign, Collections, Events und Exception Handling vertieft die C# .NET Aufbau-Schulung für objektorientierte Lösungen. Vor einer Code-Modernisierung müssen jedoch sämtliche Auslieferungskomponenten .NET 10 unterstützen.
Schritt 7: Pipelines, Container und IIS aktualisieren
Ein erfolgreicher lokaler Build sagt nichts über die Produktionsumgebung aus. Alle CI/CD-Agenten benötigen das freigegebene SDK oder die passende Runtime. Container-Builds wechseln auf Images wie mcr.microsoft.com/dotnet/sdk:10.0 und mcr.microsoft.com/dotnet/aspnet:10.0.
Der Tag 10.0 kann auf ein neueres Image zeigen. Reproduzierbare Builds verwenden deshalb eine freigegebene Image-Version oder einen Digest. IIS-Server erhalten das .NET-10-Hosting-Bundle, wobei Architektur, Anwendungspool und Runtime-Konfiguration zum veröffentlichten Artefakt passen müssen.
Bei self-contained Deployments werden Runtime Identifier, Trimming, Single-File-Publishing und native Abhängigkeiten für jede Zielplattform erneut getestet. Auch angebundene Systeme müssen die neuen Artefakte verarbeiten:
- Deployment-Manifeste
- Health Checks und Telemetrie-Agenten
- Security-Scanner
- Software Bills of Materials
- Artefakt- und Container-Registries
Pipelines, Container und Auslieferungsautomatisierung sind auch Themen der DevOps-Schulungen. Nach der Infrastrukturumstellung entscheidet eine produktionsähnliche Testfolge über die Freigabe.
Schritt 8: Integration, Leistung, Deployment und Rollback testen
Die Freigabe braucht mehr als Unit-Tests. Die Regressionstests decken die Schnittstellen und Abläufe ab, die sich durch Runtime, Framework oder Pakete verändern können:
- Integrations- und End-to-End-Tests
- Vertragstests für externe Schnittstellen
- Datenbankzugriffe und Transaktionen
- Authentifizierung und Autorisierung
- Serialisierung und Deserialisierung
- Native Bibliotheken und Betriebssystemaufrufe
Leistungstests vergleichen Latenz und Durchsatz mit der .NET-8-Baseline. CPU-Auslastung, Arbeitsspeicher, Startzeit und Fehlerrate ergänzen den Vergleich. Datenbestand, Hardware und Lastprofil bleiben dabei unverändert.
Eine produktionsähnliche Umgebung deckt Fehler in Konfigurationsdateien, Secret Stores, Zertifikaten und Netzwerkregeln auf. Blue-Green- oder Canary-Deployments werden einschließlich ihrer Health Checks ausgeführt. Datenbankänderungen folgen dem Expand-and-Contract-Muster, damit die alte und die neue Anwendungsversion während des Übergangs mit demselben Schema arbeiten können.
Messbare Release-Gates
- Alle festgelegten Test-Suites laufen erfolgreich
- Leistungsmetriken bleiben innerhalb der projektspezifischen Grenzwerte
- Monitoring, Logging und Alarmierung erfassen die neue Runtime
- Installation und Rollback wurden mit den vorgesehenen Artefakten ausgeführt
- Das vorherige Artefakt startet mit der vorgesehenen Konfiguration
Die Rollback-Probe stellt das vorherige Artefakt, seine Konfiguration und den kompatiblen Datenbankstand wieder her. Nach dieser Probe kann ein Modernisierungswerkzeug die verbleibenden mechanischen Codeänderungen unterstützen.
Was ersetzt den eingestellten .NET Upgrade Assistant?
GitHub Copilot app modernization for .NET übernimmt die Analyse- und Änderungsvorschläge des eingestellten .NET Upgrade Assistant. Der enthaltene GitHub Copilot Modernization Agent untersucht Projekte und Abhängigkeiten, erstellt einen Upgrade-Plan und schlägt Codeänderungen vor. Verfügbarkeit und Funktionsumfang hängen von der eingesetzten Visual-Studio-Version sowie der GitHub-Copilot-Lizenz ab.
Das Werkzeug liefert einen Ausgangspunkt, aber keine Produktionsfreigabe. Das Team prüft weiterhin Paketversionen, sicherheitsrelevante Änderungen, generierten Code und die Auswirkungen auf den Betrieb. Jede vorgeschlagene Änderung durchläuft dieselben Builds, statischen Analysen und automatisierten Tests wie manuell geschriebener Code.
Die endgültige Entscheidung trifft deshalb nicht der Agent, sondern die folgende Checkliste mit den zuvor festgelegten Release-Gates.
Deine finale Checkliste für die .NET-8-zu-.NET-10-Migration
- Für jedes System sind Verantwortung und Kritikalität dokumentiert
- Target Framework, Runtime und Bereitstellungsart stehen im Inventar
- Die Anwendung läuft auf dem zuletzt unterstützten .NET-8-Patch
- Messwerte und Testergebnisse der .NET-8-Baseline sind gespeichert
- Das freigegebene .NET-10-SDK ist über global.json festgelegt
- Pakete und native Abhängigkeiten wurden für net10.0 geprüft
- Build-Agenten, Container und Hosting-Komponenten unterstützen .NET 10
- Plattformwechsel und C#-14-Refactoring liegen in getrennten Pull Requests
- Monitoring und Alarmierung erkennen die neue Runtime
- Der Rollback wurde mit den vorgesehenen Produktionsartefakten ausgeführt
Lege als nächsten Schritt eine gemeinsame Inventarliste für Entwicklung, Betrieb und Anwendungseigentümer an und beginne mit den geschäftskritischen .NET-8-Systemen.