Entwicklung & Code
Domain-driven Design: Beschreibungssprache ESDM legt das Modell neben den Code
Domain-driven Design (DDD) und Event Sourcing leben von einem präzisen Vokabular. Aggregates, Bounded Contexts, Process Managers, Read Models, Context Mappings: Wer in diesen Begriffen denkt, hat ein gemeinsames Werkzeug, um über fachliche Systeme zu sprechen. Solange das Gespräch während eines Workshops live stattfindet, funktioniert das verlässlich. Das Modell ist konsistent, weil alle Beteiligten es gleichzeitig im Kopf tragen.
Weiterlesen nach der Anzeige

Golo Roden ist Gründer und CTO von the native web GmbH. Er beschäftigt sich mit der Konzeption und Entwicklung von Web- und Cloud-Anwendungen sowie -APIs, mit einem Schwerpunkt auf Event-getriebenen und Service-basierten verteilten Architekturen. Sein Leitsatz lautet, dass Softwareentwicklung kein Selbstzweck ist, sondern immer einer zugrundeliegenden Fachlichkeit folgen muss.
Sobald der Workshop jedoch endet, beginnt das Problem. Das Modell verlässt den Raum nicht als gemeinsames Artefakt, sondern als Sammlung von Bruchstücken: ein paar Folien aus dem letzten Review, ein Whiteboard-Foto, eine README.md, verstreute Code-Kommentare, vielleicht ein Diagramm im Wiki. Jede dieser Quellen ist plausibel, aber keine ist autoritativ. In diesem Beitrag stelle ich die von meiner Firma the native web entwickelte Sprache ESDM (Event-Sourced Domain Modeling) vor und beschreibe, warum sie aus meiner Sicht die richtige Antwort auf dieses Problem ist.
Wohin Modelle verschwinden, sobald der Workshop endet
Das eigentliche Drama spielt sich in den Wochen nach dem Workshop ab. Ein Entwickler reicht eine Refactoring-Änderung ein, die einen Aggregatnamen umbenennt. Das Code Review winkt sie durch. Niemand denkt an die Folien, niemand öffnet das Wiki, niemand sucht das Whiteboard-Foto wieder heraus. Das Modell auf der Platte verändert sich, das Modell im Kopf der anderen bleibt unverändert, und der Drift beginnt.
Sechs Monate später kommt eine neue Kollegin ins Projekt. Sie liest die Folien aus dem Onboarding, weil das die einzige zusammenhängende Beschreibung ist, die sie findet. Was sie liest, stimmt nicht mehr mit der Realität überein. Ein Bounded Context heißt anders, ein Event existiert nicht mehr, ein ehemals Aggregat ist in zwei zerlegt worden. Die Folien sind kein Modell, sie sind ein Foto eines Modells aus einem bestimmten Monat.
In dieser Lage gibt es eigentlich nur drei mögliche Quellen der Wahrheit, und keine davon ist eine gute: Die Folien sind veraltet, das Wiki ist veraltet, und der Code beschreibt das Modell nicht, sondern führt es aus. Wer die fachliche Wahrheit wissen will, muss aus dem Code rückwärts rekonstruieren, was die ursprüngliche Idee einmal war. Das ist anstrengend, fehleranfällig und nicht skalierbar.
Weiterlesen nach der Anzeige
Der Kern des Problems ist, dass das Modell kein erstklassiges Artefakt ist. Es hat keinen festen Ort, kein verbindliches Format, keine prüfbaren Eigenschaften. Es ist nirgendwo zu Hause, also lebt es überall ein bisschen, und überall ein bisschen heißt im Zweifel nirgendwo richtig.
Was eine Modellierungssprache eigentlich leisten muss
Aus diesem Befund ergibt sich eine ziemlich genaue Anforderungsliste an eine Lösung. Das Modell muss versionierbar sein, also als Text vorliegen, den eine Versionsverwaltung sinnvoll diffen kann. Es muss neben dem Code im Repository leben, damit derselbe Pull-Request, der den Code ändert, auch das Modell einbezieht.
Es muss prüfbar sein, in dem Sinne, dass eine Maschine bestimmte strukturelle Aussagen über das Modell automatisch validieren kann. Ob jedes Aggregat seine Events benennt, ob jedes Event einen Erzeuger hat, ob jeder Context-Mapping-Verweis auf einen tatsächlich existierenden Bounded Context zeigt: Solche Fragen darf nicht der Lesende beantworten müssen, sondern die Werkzeugkette.
Es muss von Werkzeugen lesbar sein, also einer eindeutigen Grammatik folgen. Sobald das Format steht, lassen sich Validatoren, Generatoren, IDE-Integrationen und KI-gestützte Modellierungswerkzeuge dagegen bauen. Dieser Punkt klingt wie ein Nebensatz, ist aber der Hebel, der eine Sprache von einer Konvention unterscheidet.
Und es muss frei von Dialekten sein. Ein Format, das sich pro Team konfigurieren lässt, beschreibt am Ende keine gemeinsame Sprache, sondern eine Familie verwandter Privatsprachen. Der Wert eines geteilten Modells kollabiert, sobald jedes Projekt seine eigenen Regeln zuschneidet. Wer sich auf die Sprache verlassen können will, braucht eine Sprache, die nicht jede Stelle einzeln aushandelbar ist.
ESDM legt das Modell neben den Code
ESDM, kurz für Event-Sourced Domain Modeling, ist genau die Sprache, die diesen Anforderungen entspricht. Die YAML-basierte Sprache mit eingebauter Werkzeugkette ist auch für den kommerziellen Einsatz kostenfrei. Modelle bestehen aus Dateien mit der Endung .esdm.yaml, jede Datei enthält ein oder mehrere Dokumente, jedes Dokument deklariert eine apiVersion und einen kind-Eintrag und beschreibt damit genau ein Element der Domäne.
Die Werkzeugkette ist ein einziges Binary, das auf macOS, Linux und Windows läuft. Das Schema, gegen das die Werkzeuge validieren, ist im Binary eingebettet, nicht aus dem Netz nachgeladen. Das macht ESDM vollständig offline-fähig: Es funktioniert in abgeschotteten Build-Umgebungen, in CI-Runnern ohne ausgehende Netzverbindung und auf dem Laptop im Zug.
Der Effekt dieses Aufbaus ist greifbar. Das Modell liegt nicht mehr in einem entfernten System, sondern direkt im Repository, in einem Verzeichnis neben dem Code. Wer den Code bearbeitet, sieht das Modell. Wer das Modell bearbeitet, sieht es im Diff des Pull Request. Niemand muss sich daran erinnern, dass es das Modell gibt; es liegt sichtbar im Verzeichnisbaum.
Genauso wichtig ist, was sich dadurch im Review-Verhalten verändert. Sobald das Modell Teil des Repositorys ist, wird es Teil des Code-Reviews. Eine Refactoring-Änderung, die einen Aggregatnamen umbenennt, muss die entsprechende .esdm.yaml-Datei in derselben Änderung mitbewegen, sonst meldet der Linter den Bruch. Der Drift wird nicht durch Disziplin verhindert, sondern durch die Werkzeugkette.
Vokabular und Erweiterungen
Inhaltlich deckt ESDM das Vokabular ab, mit dem Domain-driven Design und Event Sourcing operieren. Domains und Subdomains beschreiben den fachlichen Rahmen. Bounded Contexts grenzen Vokabularien voneinander ab. Aggregates, Dynamic Consistency Boundaries (DCBs) und Process Manager tragen die Konsistenzregeln. Events und Commands tragen die Fakten und die Absichten. Read Models und Queries beschreiben die Leseseite. Context Mappings beschreiben, wie Bounded Contexts sich aufeinander beziehen. Actors, Domain Services, Event Handler, Policies und External Systems schließen die Lücken, die in realen Systemen sonst implizit bleiben.
Damit deckt der Kern den Schreib- und Leseweg eines Event-getriebenen Systems ab, von der Absicht über das Faktum bis zur projizierten Sicht. Das Modell ist nicht ausführbar; es beschreibt das Was, nicht das Wie. Diese Trennung ist die Voraussetzung dafür, dass dasselbe Modell für unterschiedliche Implementierungen tragen kann, ohne sich an eine Laufzeit zu binden.
Über den Kern hinaus gibt es Erweiterungen, die Artefakte rund um das eigentliche Modellieren beschreiben. Die Domain-Storytelling-Erweiterung hält Entdeckungsgeschichten als eigene Dokumentenart fest, mit Akteurinnen und Akteuren, Arbeitsobjekten und den Aktivitäten, die sie verbinden. Die Given-When-Then-Erweiterung erfasst Verhaltensbeispiele, also vorausgehende Events, eine auslösende Handlung und die erwarteten Ausgänge.
Beide Erweiterungen folgen denselben Konventionen wie der Kern und werden von derselben Werkzeugkette validiert. Sie injizieren aber keine neuen Bausteine in den Kern, und ein Kerndokument validiert nie gegen ein Erweiterungsschema. Diese Asymmetrie ist bewusst: Sie hält den Kern schmal und erlaubt es trotzdem, die Oberfläche der Sprache mit der Zeit wachsen zu lassen, ohne den Bestand zu gefährden.
Die Versionierung des Schemas folgt derselben Disziplin, die Sie aus Kubernetes-API-Gruppen kennen. Jedes Dokument deklariert eine apiVersion, und diese Version bindet das Dokument an eine konkrete Schema-Generation. Non-breaking Changes erhöhen die Schema-Revision, ohne die apiVersion anzufassen; Breaking Changes wandern in eine neue Hauptversion, und alte Dokumente validieren weiter gegen das alte Schema. Stabilität ist die Voreinstellung, Wechsel sind eine bewusste Entscheidung.
Der Linter hält das Modell sauber
Im Zentrum der Werkzeugkette steht der Linter. Er liest die .esdm.yaml-Dateien unter einem Verzeichnis, parst sie gegen das eingebettete Schema, prüft eine feste Liste struktureller und modellierender Regeln und meldet jede Verletzung als Diagnose mit Datei, Zeile und Spalte. Eine saubere Modellierung erzeugt keine Ausgabe und verlässt das Werkzeug mit Statuscode 0.
Der feste Regelkatalog ist eine bewusste Entscheidung. Es gibt keine Projektkonfigurationsdatei, keine Severity-Schalter, kein Abschalten einzelner Regeln. Eine Regel gilt oder sie gilt nicht; diese Entscheidung trifft die Werkzeugkette, nicht das Repository. Der Preis dafür ist, dass eine Regel gelegentlich strenger wirkt, als die konkrete Situation zu verlangen scheint. Der Gewinn ist, dass jedes ESDM-Modell, egal von welchem Team, dieselben Eigenschaften garantiert. Eine Sprache mit Schaltern beschreibt am Ende viele Sprachen mit demselben Namen, und der Wert des gemeinsamen Modells geht verloren.
Diagnosen sind Orte, keine Stack Traces. Jede Meldung verweist auf eine Datei, eine Zeile und eine Spalte und beschreibt das Problem in einem kurzen Satz, der das Vokabular der Modellierenden spricht, nicht das der Werkzeugkette. Es gibt keine Fehlernummern, die in einer Tabelle nachgeschlagen werden müssten, und keine internen Aufrufketten, die nach außen sichtbar wären.
Die volle Wirkung entfaltet der Linter, sobald er in der Continuous-Integration-Pipeline läuft. Ein Pull Request, der ein Aggregat umbenennt, ohne das Modell mitzuziehen, scheitert am CI-Schritt und wird nicht gemergt. Ein neues Event ohne Erzeuger oder ohne Konsumenten scheitert genauso. Der Drift, der vorher durch Disziplin verhindert werden musste, wird durch eine kurze, präzise Diagnose verhindert.
Konsistent mit ESDM
Konkret zahlt sich diese Architektur in mehreren Szenarien aus. Im Event-Storming-Workshop oder in der Domain-Storytelling-Sitzung gibt ESDM den Entdeckungen einen Ort, an dem sie überleben. Statt nach dem Workshop Fotos zu archivieren, schreibt man die Events, Commands, Akteurinnen und Akteure und Bounded Contexts in .esdm.yaml-Dateien und bekommt sofort Rückmeldung, ob das Modell intern konsistent ist. Ein Aggregat, das keine Events besitzt, ein Command, das niemand publiziert, ein Process Manager ohne Auslöser: Solche Lücken zeigt der Linter, bevor sie sich als unausgesprochene Annahmen verfestigen.
Bei einem bestehenden System, dessen Modell nur in den Köpfen der Beteiligten existiert, lässt sich ESDM als nachträgliches Beschreibungswerkzeug einsetzen. Beginnen Sie mit den Konsistenzeinheiten: jedes Aggregat, jeden Process Manager, jede Dynamic Consistency Boundary (DCB), jedes Read Model. Listen Sie die Events auf, die jeweils publiziert werden, und die Commands, die akzeptiert werden. Die Übung selbst legt Lücken frei, und am Ende steht ein Modell, das mit dem Code mitwachsen kann, statt ihm hinterherzulaufen.
Sobald das Modell vorliegt, wird es zum natürlichen Gesprächsformat mit fachlichen Stakeholderinnen und Stakeholdern. Der view-Befehl rendert das Modell als hierarchische Übersicht, von der Domäne über die Subdomains und Bounded Contexts bis hinunter zu den Konsistenzeinheiten und ihren Events und Commands. Diese Übersicht ist auf Knopfdruck verfügbar und entspricht garantiert dem Quellzustand. Domänenexpertinnen und Domänenexperten lesen darin dieselben Begriffe, die sie selbst verwenden, und können ohne Umweg über Implementierungsdetails Rückmeldung geben.
In Systemen mit mehreren Teams und gemeinsamen Bounded Contexts macht ESDM die Verträge zwischen den Teams explizit. Ein Context Mapping beschreibt die Beziehung zwischen zwei Bounded Contexts, ein teamübergreifender Event-Verweis ist eine geprüfte Tatsache und keine Vermutung. Was zwischen zwei Teams einmal vereinbart und im Modell festgehalten ist, prüft die Werkzeugkette danach automatisch. Die fachliche Annahme ist nicht mehr nur eine geteilte Erinnerung, sondern eine prüfbare Aussage.
Schließlich passt ESDM erstaunlich gut zu Workflows mit KI-Unterstützung. Das YAML ist schlicht genug, dass große Sprachmodelle es direkt lesen und schreiben, und das fixierte Schema und das benannte Vokabular geben dem Modell genau die Leitplanken, die es braucht, um etwas Kohärentes zu produzieren. Ein Modell aus einem Domänengespräch zu skizzieren oder aus einem Code-Bestand Kandidaten für Aggregates und Events zu extrahieren, sind Aufgaben, die sich mit dem ESDM-Vokabular zuverlässiger und überprüfbarer lösen lassen, als wenn das Modell in Prosa beschrieben wird.
Was ESDM bewusst nicht ist
Genauso wichtig wie die Beschreibung dessen, was ESDM ist, ist auch die Abgrenzung zu dem, was es nicht ist. ESDM ist kein Eventstore. Es speichert und liest keine Ereignisse, es legt nichts in eine Datenbank ab. ESDM beschreibt lediglich, welche Events es überhaupt geben soll.
ESDM ist auch kein Framework. Es schreibt keinen Programmierstil vor, keine Klassenhierarchie, keine Annotationen, keinen bestimmten Aufbau eines Service. Welche Sprache, welches Framework, welche Bibliothek Sie für die tatsächliche Implementierung verwenden, bleibt vollständig Ihnen überlassen. ESDM mischt sich in diese Entscheidungen nicht ein.
ESDM ist kein Codegenerator und keine Laufzeitumgebung. Es erzeugt aus dem Modell keine Klassen, keine Migrationen, keine API-Endpunkte. Es führt nichts aus. Diese Entscheidung ist keine Lücke, sondern Programm: Eine Modellierungssprache, die zugleich generieren oder ausführen will, zwingt mich zu Laufzeitentscheidungen, und eine Laufzeit, die zugleich modelliert, vergräbt das Modell unter Implementierungsdetails.
ESDM hält die beiden Seiten getrennt. Es ist eine deskriptive Schicht, die neben dem Code lebt und das Modell ehrlich hält, und es ist genau das, nichts darüber hinaus. Diese Sparsamkeit ist die Voraussetzung dafür, dass ESDM sich frei mit dem kombinieren lässt, was Sie tatsächlich in Produktion betreiben.
Lesen Sie auch
(rme)
Entwicklung & Code
Kommentar: Das Ende der SaaS-Gelddruckmaschine
Als der Hedgefonds TCI jüngst seinen Microsoft-Anteil drastisch zusammenstrich, klang das erst einmal nach einer dieser Meldungen, die im Strom der Finanznachrichten untergehen. Doch diesmal lohnt der zweite Blick. TCI-Gründer Chris Hohn gehörte jahrelang zu den großen Profiteuren des Microsoft-Booms, fast 400 Prozent Kursgewinn seit 2017 sprechen eine deutliche Sprache. Wenn ausgerechnet so ein Investor kalte Füße bekommt, geht es nicht um schwache Quartalszahlen. Dann steht die ökonomische Grundlage der Softwareindustrie zur Debatte.
Weiterlesen nach der Anzeige

Moritz Förster schreibt seit 2012 für die iX und heise online. Er betreut neben dem iX-Channel den Bereich Arbeitsplatz.
Die Sprengkraft der KI-Revolution liegt nicht darin, dass sie eine bestimmte Software ersetzt. Sondern darin, dass sie das Geschäftsmodell dahinter pulverisiert. Willkommen in der SaaSpocalypse.
Das Geschäftsmodell hinter der Lizenzmaschine
Zwei Jahrzehnte lang funktionierte Unternehmenssoftware nach einem stabilen Prinzip. Jede Aufgabe bekam ihre eigene Anwendung: Texte in Word, Tabellen in Excel, Kundendaten in Salesforce, Bildbearbeitung in Photoshop. Unternehmen zahlen Lizenzen pro Nutzer, pro Arbeitsplatz, pro Monat. Je tiefer die Software in die Arbeitsabläufe einsickerte, desto verlässlicher sprudelten Umsatz und Margen. Der Wert lag dabei nie nur im Programmcode, sondern in einer schlichten Tatsache: Menschen mussten ihre Arbeit innerhalb dieser Anwendungen erledigen.
Genau diese Logik bröckelt nun. KI-Assistenten verändern nicht bloß einzelne Funktionen, sondern die Schnittstelle zur Arbeit selbst. Wer heute Copilot, Gemini oder ChatGPT nutzt, klickt sich nicht mehr durch klassische Menüs. Stattdessen formuliert der Nutzer Ziele: „Fasse die wichtigsten Punkte aus diesen Mails zusammen.“ „Bau eine Präsentation aus den Quartalszahlen.“ Die Arbeit wandert Schritt für Schritt vom Menschen zur Maschine. Und je besser diese Systeme werden, desto unwichtiger wird die Anwendung im Hintergrund.
Microsoft sägt am eigenen Ast
Das zeigt sich ausgerechnet bei Microsoft selbst. Seinen Copilot präsentiert der Konzern längst nicht mehr als Zusatzfunktion für Word oder Excel. Das Ziel ist ein Assistent, der quer über alle Anwendungen arbeitet. Der Nutzer redet mit dem Agenten – nicht mehr mit dem Programm. Wird die KI zur Bedienoberfläche der Wissensarbeit, verliert die klassische Anwendung ihre Rolle als zentraler Zugangspunkt. Sie wird zur Infrastruktur.
Weiterlesen nach der Anzeige
Aus Nutzersicht klingt das verlockend. Für die Softwareindustrie ist es eine Bedrohung. Denn Software-as-a-Service-Modelle leben davon, dass jeder Mitarbeiter Zugang zu einzelnen Anwendungen braucht. KI-Agenten lösen diese Kopplung auf. Warum Hunderte Vollzugänge bezahlen, wenn ein paar Agenten einen Großteil der Arbeit erledigen?
Die Börse handelt bereits die nächste Ära
Die Nervosität an den Börsen kommt nicht von ungefähr. Microsoft, Salesforce, Adobe und Oracle verdienen weiterhin Milliarden. Aber die Zweifel wachsen, ob die fetten Margen der SaaS-Ära dauerhaft Bestand haben. Bemerkenswert dabei: Die Disruption entsteht innerhalb der Plattformen selbst. Microsoft demonstriert mit Copilot genau die Entwicklung, die das klassische Softwaremodell untergräbt. Der Konzern treibt die Entkopplung von Nutzer und Anwendung selbst voran.
Börsen handeln spekulative Erwartungen, keine Gegenwart. Für Investoren genügt die Aussicht auf sinkende Preissetzungsmacht, um Bewertungen neu zu sortieren. Die Machtfrage lautet deshalb nicht mehr, wer die beste Software baut. Sondern wer künftig die Bedienoberfläche der Arbeit kontrolliert.
Das erklärt, warum TCIs Teilverkauf mehr ist als ein gewöhnliches Börsensignal. Der Fonds stößt Microsoft-Aktien nicht ab, weil Office schwächelt oder Azure plötzlich Verluste schreibt. TCI reagiert auf eine tiefere Unsicherheit: KI löst eben nicht einfach Programme ab. Sie ersetzt die ökonomische Logik, auf der die Softwareindustrie aufgebaut wurde. Und genau deshalb droht die SaaSpocalypse.
Bei diesem Kommentar handelt es sich um das Editorial der iX 6/2026, die am 22. Mai erscheint.
(fo)
Entwicklung & Code
Fedora Hummingbird Linux: Neue Container-basierte Distribution
Neben viel KI und Virtualisierung gab es auf dem Red Hat Summit auch Neuigkeiten im Bereich der Linux-Distribution: Fedora Hummingbird Linux – auch HummingbirdOS genannt – ist da. Hierbei handelt es sich um eine vollständig Container-basierte Distribution. Gleich mehrere bereits bekannte Projekte vereinen sich hier: Zum einen natürlich Software aus dem Fedora-Universum, aber auch rpm-ostree, das von Fedora CoreOS und auch Silverblue bekannt ist.
Weiterlesen nach der Anzeige
Statt über einen traditionellen Paketmanager kommen Software-Aktualisierungen über sogenannte Transaktionen in das System. Das ist vergleichbar mit einem Git-Commit mit zwei Zuständen: dem aktuellen und dem nächsten. HummingbirdOS greift ebenfalls auf das bootc-Projekt zurück. Dabei geht es um sogenannte „bootfähige“ Container, die mit einem Linux-Kernel und systemd ausgestattet sind. Sie können als normale Container laufen oder über bootc wie ein klassisches Linux starten.
Die letzte Zutat für das neue Fedora Linux ist das Hummingbird-Projekt. Es stellt minimalistische und gehärtete Container bereit. Letzteres bedeutet, dass es idealerweise keine bekannten ungepatchten Sicherheitslücken bezüglich der installierten Software gibt. Ziel ist, dass jeder Container nur eine Funktion hat.
HummingbirdOS ausprobieren
Fedora Hummingbird Linux ist noch in einem frühen Stadium. Interessierte können sich aber schon ein Abbild aus der Container-Registry der Hummingbird-Community herunterladen. Ferner kann man das System auch als virtuelle Maschine betreiben. Dazu muss man das Container-Abbild per bootc-image-builder umwandeln. Das Resultat ist entweder eine virtuelle Festplatte oder Installations-CD. Erstere bindet der Anwender entweder in den Hypervisor oder Cloud-Account ein. Danach startet HummingbirdOS analog zu den anderen virtuellen Maschinen. Die Installations-CD benutzt das bekannte Werkzeug Anaconda.
Bei den von Red Hat angedachten Anwendungsfällen schließt sich der Bogen zurück zur KI. HummingbirdOS soll laut Ankündigung als Plattform für KI-Agenten dienen. Designbedingt bietet es aktuelle Software mit minimaler Angriffsfläche. Unterstützung für Nutzer ist über den „Cooperative Community Support“ geplant. Hier können zahlende Red-Hat-Kunden auch Hilfe für bestimmte Projekte außerhalb des Enterprise-Umfeldes bekommen.
Lesen Sie auch
(fo)
Entwicklung & Code
.NET 11.0 Preview 4: Ein bunter Strauß von API-Erweiterungen
Die vierte Vorschauversion der kommenden .NET-Version 11.0 ist erschienen und steht zum Download bereit. Parallel dazu hat Microsoft auch die Version 11811.120 von Visual Studio 2026 Insiders veröffentlicht, die zum Entwickeln von .NET-11.0-Anwendungen benötigt wird. Alternativ ist eine Arbeit mit Visual Studio Code und dem im SDK mitgelieferten Kommandozeilencompiler möglich.
Weiterlesen nach der Anzeige

Dr. Holger Schwichtenberg hat Fachbücher zu .NET 10.0, C# 14.0, Blazor 10.0 und Entity Framework Core 10.0 veröffentlicht. Er arbeitet als Berater und Trainer bei www.IT-Visions.de.

Installation des .NET 11.0 SDK in der Version Preview 4
(Bild: King / stock.adobe.com)

Das ist neu in .NET 11.0: Dr. Holger Schwichtenberg und weitere Experten präsentieren am 17. November 2026 auf der Online-Konferenz betterCode() .NET 11.0 die Änderungen für Entwicklerinnen und Entwickler in .NET SDK, C# 15.0 und mehr. Bis zur Veröffentlichung des Programms sind vergünstigte Blind-Bird-Tickets verfügbar.
Viel Neues für den Prozessstart
Die Klasse System.Diagnostics.Process zur Verwaltung von Betriebssystemprozessen gibt es seit Version 1.0 des klassischen .NET Framework aus dem Jahr 2002. Prozesse startet man seitdem, indem man eine neue Instanz der Klasse erzeugt. Seit .NET Framework 2.0 (Jahr 2005) gibt es alternativ die statische Methode Process.Start(). 21 Jahre später ergänzt Microsoft nun weitere alternative statische Methoden zum Prozessstart: Process.Run() und Process.RunAsync() sowie Process.RunAndCaptureText() und Process.RunAndCaptureTextAsync(). Das letztgenannte Pärchen liefert ein ProcessTextOutput-Objekt, mit dem man direkt auf Standardausgabe (ProcessTextOutput), Standardfehlerausgabe (StandardError) und Rückgabewert (ExitStatus.ExitCode) zugreifen kann, mit deutlich weniger Programmcode als dies bei der alten Start()-Methode notwendig ist, siehe Listing.
Ein Abbruch des Kindprozesses ist über ein Cancellation-Token möglich. Anders als bei der Start()-Methode kehren alle neuen Methoden mit „Run“ im Namen erst zum Aufrufer zurück, wenn der Kindprozess beendet ist. Entwicklerinnen und Entwickler können dabei allerdings keine Ausgaben des Prozesses verarbeiten, während er läuft.
CancellationTokenSource cts = new CancellationTokenSource();
ProcessTextOutput result = await Process.RunAndCaptureTextAsync(
"robocopy.exe", [@"t:\Daten", @"t:\Daten_Backup", "/MIR", "/IS"], cts.Token);
CUI.Print("Neuer Prozess mit ID #" + result.ProcessId + " ist beendet!");
CUI.Line("StandardOutput");
CUI.Print(result.StandardOutput);
CUI.Line("StandardError");
CUI.PrintError(result.StandardError);
CUI.Line("ExitStatus");
CUI.Print("Canceled? " + result.ExitStatus.Canceled);
if (result.ExitStatus.HasValue && !result.ExitStatus.IsEmpty) PrintStatus(result.ExitStatus.ExitCode);
Listing 1: Einsatz der neuen Methode Process.RunAndCaptureTextAsync()
Weiterlesen nach der Anzeige
Eine weitere hinzugefügte Methode zum Prozessstart ist Process.StartAndForget() zum Start eines Prozesses, ohne auf den erfolgreichen Start zu warten und ohne direkte Interaktionsmöglichkeiten mit dem neuen Prozess. Man kann lediglich über die zurückgelieferte Prozess-ID den neuen Prozess von außen überwachen, hat aber keinen Zugriff auf den Rückgabewert des Prozesses.
int processId = Process.StartAndForget(
"robocopy.exe", [@"t:\Daten", @"t:\Daten_Backup", "/MIR", "/IS"]);
CUI.Print("Neuer Prozess mit ID #" + processId + " ist gestartet!");
var p = Process.GetProcessById(processId);
while(!p.HasExited)
{
CUI.BusyIndicator();
Thread.Sleep(500);
}
CUI.Line("Neuer Prozess mit ID #" + processId + " ist beendet!");
// PrintStatus(p.ExitCode); // System.InvalidOperationException: 'Process was not started by this object, so requested information cannot be determined.'
Listing 2: Einsatz der neuen Methode Process.StartAndForget()
In der Klasse ProcessStartInfo, die bei Process.Start() verwendet wird, gibt es auch zwei neue Boolean-Optionen: Neu sind zum einen ProcessStartInfo.StartDetached zum Start eines unabhängigen Prozesses mit eigener Konsole, der weiterlebt, auch wenn der startende Prozess beendet wird. Mit ProcessStartInfo.KillOnParentExit erreicht man zum anderen, dass der Kindprozess endet, wenn der startende Prozess endet. Wenn man beide Optionen in Kombination einsetzt, erhält man eine separate Konsole, die aber endet, wenn der startende Prozess endet. Während ProcessStartInfo.StartDetached auf allen Plattformen läuft, meldet ProcessStartInfo.KillOnParentExit aktuell, dass es nur auf Windows funktioniert, denn im Quellcode bei Microsoft steht:
[SupportedOSPlatform("windows")]
public bool KillOnParentExit { get; set; }
In einem Blogeintrag findet man schon den Hinweis darauf, dass Implementierungen für Android und Linux in Arbeit sind.
Für mit Process.Start() gestartete Prozesse gibt es auch die neuen Methoden ReadAllText() und ReadAllTextAsync(), mit denen man von einem beendeten Prozess gleichzeitig die Standardausgabe und die Fehlerausgabe erhalten kann:
process.WaitForExit();
(string output, string error) = process.ReadAllText();
Im Gegensatz zu dem bisherigen Ansatz
string output = process.StandardOutput.ReadToEnd();
string error = process.StandardError.ReadToEnd();
besteht bei den neuen Methoden nicht die Gefahr eines Deadlocks.
(De)-Komprimierung mit Span
In .NET 11.0 Preview 1 hatte Microsoft die Zstandard-Komprimierung ergänzt. Die Klassen ZstandardEncoder und ZstandardDecoder bieten dabei genauso wie die bereits in .NET Core 2.1 eingeführten Klassen BrotliEncoder und BrotliDecoder die Möglichkeit, beim Komprimieren und Dekomprimieren mit den Typen Span und ReadOnlySpan zu arbeiten, ohne die aufwendige Speicherallokation bei Streams. Nun liefert Microsoft diese Option auch für die älteren Klassen ZLibEncoder, DeflateEncoder und GZipEncoder sowie die zugehörigen Decoder, siehe Listing.
CUI.H1($"Komprimiere Datei {BIGFILEPATH} via Span");
ReadOnlySpan sourceSpan = File.ReadAllBytes(BIGFILEPATH);
Console.WriteLine("Länge=" + sourceSpan.Length);
long maxCompressedLength = ZLibEncoder.GetMaxCompressedLength(sourceSpan.Length);
Span compressedSpan = new byte[maxCompressedLength];
// ZLibEncoder, DeflateEncoder, GZipEncoder, ZstandardEncoder oder BrotliEncoder
using ZLibEncoder encoder = new();
OperationStatus status = encoder.Compress(
sourceSpan, compressedSpan, out int bytesConsumed, out int bytesWritten,
isFinalBlock: true);
PrintStatus(compressedSpan, status);
CUI.H1($"Dekomprimieren aus Span");
// ZLibDecoder, DeflateDecoder, GZipDecoder, ZstandardDecoder oder BrotliDecoder
using ZLibDecoder decoder = new();
byte[] decompressedSpan = new byte[sourceSpan.Length];
OperationStatus decompressStatus = decoder.Decompress(
compressedSpan,
decompressedSpan,
out int compressedBytesConsumed,
out int decompressedBytesWritten);
PrintStatus(decompressedSpan, decompressStatus);
Listing 3: Komprimierung und Dekomprimierung mit Span
Parsen von Hex-Werten
Die Fließkommazahltypklassen Half, Single und Double können in den Methoden Parse() und TryParse() auch Zeichenketten mit Hexadezimalzahlen auswerten. Dazu müssen Entwicklerinnen und Entwickler aber die Option NumberStyles.HexFloat angeben:
static void TestDouble(double d, string doubleAsString )
{
string hex = d.ToString("X");
Console.WriteLine(hex);
double d1a = double.Parse(hex, NumberStyles.HexFloat);
Console.WriteLine(d1a);
CUI.Success(d1a == d); // True
double.TryParse(hex, NumberStyles.HexFloat, null, out double d1b);
Console.WriteLine(d1b);
CUI.Success(d1b == d); // True
}
Prüfung auf Gültigkeit bei UTF8 und UTF16
Die Klassen System.Text.Unicode.Utf8 und System.Text.Unicode.Utf16 bieten nun zwei neue Methoden: IsValid() und IndexOfInvalidSubsequence(). Damit lässt sich nun leichter die Gültigkeit einer Unicode-Zeichenkette prüfen und zumindest die erste fehlerhafte Stelle ermitteln:
ReadOnlySpan chars1 = "Gültiger Text: \uD83D\uDC4D";
Console.WriteLine(chars1);
bool check1 = Utf16.IsValid(chars1); // True
Console.WriteLine(check1);
if (check1) CUI.Success("OK");
else CUI.Warning("Fehler bei Zeichen: " + Utf16.IndexOfInvalidSubsequence(chars1));
ReadOnlySpan chars2 = "Ungültiger Text: \uD83D";
Console.WriteLine(chars2);
bool check2 = Utf16.IsValid(chars2); // False
if (check2) CUI.Success("OK");
else CUI.Warning("Fehler bei Zeichen: " + Utf16.IndexOfInvalidSubsequence(chars2));
Utf8JsonWriter mit abweichenden Einstellungen wiederverwenden
Bei dem im modernen .NET mitgelieferten JSON-Serialisierer, dem NuGet-Paket System.Text.Json, das auch im klassischen .NET Framework funktioniert, bietet die schon vorher bestehende Methode Reset() in der Klasse Utf8JsonWriter nun eine Überladung, in der man via JsonWriterOptions abweichende Einstellungen festlegen kann. Entwicklerinnen und Entwickler können damit Utf8JsonWriter-Instanzen mit abweichenden Einstellungen wiederverwenden:
using var stream1 = new MemoryStream();
using var writer = new Utf8JsonWriter(stream1, new JsonWriterOptions
{
Indented = true
});
…
using var stream2 = new MemoryStream();
writer.Reset(stream2, new JsonWriterOptions
{
Indented = false
});
Im Source Generator innerhalb von System.Text.Json behebt Microsoft einige Schwächen.
-
Künstliche Intelligenzvor 3 Monaten
Top 10: Die beste kabellose Überwachungskamera im Test – Akku, WLAN, LTE & Solar
-
Social Mediavor 3 MonatenCommunity Management und Zielgruppen-Analyse: Die besten Insights aus Blog und Podcast
-
Entwicklung & Codevor 2 MonatenCommunity-Protest erfolgreich: Galera bleibt Open Source in MariaDB
-
Künstliche Intelligenzvor 2 MonatenBlade‑Battery 2.0 und Flash-Charger: BYD beschleunigt Laden weiter
-
Künstliche Intelligenzvor 2 Monaten
Top 10: Der beste Luftgütesensor im Test – CO₂, Schadstoffe & Schimmel im Blick
-
Apps & Mobile Entwicklungvor 2 MonatenMähroboter ohne Begrenzungsdraht für Gärten mit bis zu 300 m²
-
Künstliche Intelligenzvor 2 MonateniPhone Fold Leak: Apple spart sich wohl iPad‑Multitasking
-
Social Mediavor 2 MonatenVon Kennzeichnung bis Plattformpflichten: Was die EU-Regeln für Influencer Marketing bedeuten – Katy Link im AllSocial Interview
