Start Debugging

C# 14 Idee: Interceptors könnten die Source-Generation von System.Text.Json automatisch wirken lassen

Eine Community-Diskussion schlug vor, C# 14 Interceptors zu nutzen, um JsonSerializer-Aufrufe so umzuschreiben, dass sie automatisch einen generierten JsonSerializerContext verwenden und so die AOT-freundliche Source-Generation mit saubereren Aufrufstellen erhalten.

Eine der interessanteren .NET Diskussionen der letzten 24 bis 48 Stunden war eine einfache Frage: Warum fühlt sich die Source-Generation von System.Text.Json an der Aufrufstelle immer noch “manuell” an?

Der Auslöser war ein Thread vom 7. Februar 2026, der einen Ansatz vorschlug, der sehr im Geist von C# 14 ist: Interceptors, die JsonSerializer.Serialize- und JsonSerializer.Deserialize-Aufrufe so umschreiben, dass sie automatisch einen generierten JsonSerializerContext verwenden.

Die Ergonomielücke: Context funktioniert, breitet sich aber durch den Code aus

Wenn Sie in .NET 10 Trimming-Sicherheit und vorhersagbare Performance möchten, ist Source-Generation eine starke Option. Die Reibung ist, dass Sie den Kontext überall durchschleifen:

using System.Text.Json;

var foo = JsonSerializer.Deserialize<Foo>(json, FooJsonContext.Default.Foo);
var payload = JsonSerializer.Serialize(foo, FooJsonContext.Default.Foo);

Es ist explizit und korrekt, aber es ist laut. Dieses Rauschen sickert tendenziell in App-Schichten, die sich nicht um Serialisierungs-Verkabelung kümmern sollten.

Wie eine Interceptor-basierte Umschreibung aussehen könnte

Die Idee ist: Halten Sie die Aufrufstellen sauber:

var foo = JsonSerializer.Deserialize<Foo>(json);

Und lassen Sie dann einen Interceptor (zur Kompilierzeit) ihn in den kontextbasierten Aufruf umschreiben, den Sie von Hand geschrieben hätten:

var foo = JsonSerializer.Deserialize<Foo>(json, GlobalJsonContext.Default.Foo);

Wenn Sie mehrere Options-Profile haben, benötigt der Interceptor eine deterministische Zuordnung zur richtigen Context-Instanz. Genau hier beginnt der “das ist schwer”-Teil.

Die Beschränkungen, die darüber entscheiden (AOT ist der Richter)

Damit dies mehr als nur eine nette Idee ist, muss es in den Umgebungen überleben, in denen Source-Generation am wichtigsten ist:

Wenn diese Beschränkungen erfüllt sind, bekommen Sie einen seltenen Gewinn: die AOT-freundliche Pipeline beibehalten, aber die “Context-Verkabelung” aus dem Großteil Ihres Codes entfernen.

Die praktische Lehre für heute: Selbst wenn Interceptors nicht in der genau diskutierten Form landen, ist dies ein starkes Signal, dass .NET Entwickler bessere Ergonomie rund um Source-Generation wünschen. Ich würde erwarten, dass künftiges Tooling, Analyzer oder Framework-Muster sich in diese Richtung bewegen.

Quellen:

Comments

Sign in with GitHub to comment. Reactions and replies thread back to the comments repo.

< Zurück