Source Generators, NuGet-Splits und warum dein KMU das meistens falsch einordnet

Andrew Lock beschreibt, wie er sein Enum-Source-Generator-Paket aufgesplittet hat – ein lehrreiches Stück .NET-Handwerk. Aber was bedeutet das konkret für Mittelständler, die nicht Microsoft oder Spotify heißen?

⚙ KI-Entwurf Dieser Beitrag wurde automatisiert generiert und nicht redaktionell freigegeben. Behandelt ihn entsprechend.

Letzten Herbst saß ich bei einem Maschinenbauer aus dem Stuttgarter Umland. 180 Mitarbeiter, eine selbst gestrickte .NET-Warenwirtschaft, die irgendwo zwischen Framework 4.6 und .NET 8 lebt – je nach Modul. Der Entwickler, der das alles zusammenhält, heißt Thomas. Thomas ist gut. Thomas ist aber auch der Einzige, der diese Anwendung wirklich versteht.

Wir schauten uns ein Performance-Problem an einem Reporting-Modul an. Enum-Serialisierung, tausende von Iterationen pro Lauf, alles über die Standard-ToString()-Methode. Als ich Thomas fragte, ob er schon mal von Source Generators gehört habe, sah er mich an wie ich ihn gefragt hätte, ob er schon mal auf dem Mond war. Nicht weil er keine Ahnung hat – sondern weil er keine Zeit hat.


Andrew Lock ist einer der verlässlichsten .NET-Blogger da draußen, und sein aktueller Beitrag über NetEscapades.EnumGenerators ist ein gutes Stück ehrliches Open-Source-Handwerk. Kurz zusammengefasst: Er hat ein NuGet-Paket gebaut, das automatisch schnellere Enum-Operationen generiert – ToStringFast() statt ToString(), ganze 200-fache Performance-Verbesserung gegenüber .NET Framework. In einem neuen Beta-Release hat er dann Options-Typen direkt in die Attributes-DLL gepackt – das brach für viele Nutzer den Build mit CS0012. Die Lösung: Das Paket wird in drei separate Pakete aufgeteilt, sauber nach Verantwortung getrennt. Lock erklärt das transparent und ruft zur Rückmeldung auf, bevor Version 1.0.0 stabil wird.

Das ist professionelles Paket-Design. Und der Denkfehler, den er selbst gemacht hat – öffentliche Typen in eine Marker-Attribute-DLL zu legen – ist exakt das, was passiert, wenn man zu schnell neue Features schiebt ohne die Abhängigkeits-Architektur zu Ende zu denken. Gut, dass er das offen beschreibt.


Jetzt kommt der Teil, den Lock nicht schreibt – weil es nicht seine Zielgruppe ist.

Was landet das bei Thomas, dem Solo-Entwickler beim Maschinenbauer?

Erstens: Überhaupt nichts, solange Thomas auf .NET Framework 4.x sitzt. Source Generators in der Incremental-Variante – also dem Stand, auf dem NetEscapades.EnumGenerators basiert – funktionieren erst ab .NET 6 richtig. Wer noch auf dem alten Framework ist (und das sind erstaunlich viele KMU-Anwendungen), für den ist das ganze Thema akademisch.

Zweitens: Der Performance-Gewinn ist real, aber er ist nur dort relevant, wo Enums auch tatsächlich im Hot Path sitzen. Locks Benchmarks zeigen 200-fache Beschleunigung gegenüber .NET Framework. Das klingt dramatisch. Aber wenn dein Reporting-Modul 800 ms braucht, weil es 40.000 Zeilen aus einer schlecht indizierten SQL-Tabelle zieht, dann sparst du mit ToStringFast() vielleicht 12 ms – und merkst es nicht. Das ist kein Argument gegen das Paket. Es ist ein Argument dafür, erst das richtige Problem zu finden, bevor man das richtige Werkzeug einsetzt.

Drittens, und das ist der Teil, der mich in der Praxis am meisten beschäftigt: NuGet-Abhängigkeiten in KMU-Anwendungen sind oft schlechter gepflegt als die Hardware im Serverraum. Ich sehe regelmäßig Projekte, die auf beta19 eines Pakets feststecken, weil der Entwickler nach dem Update-Versuch einen Breaking Build hatte und dann nie zurückgekommen ist. Lock beschreibt genau dieses Szenario – sein beta19 hat Nutzer gebrochen. Für ein Solo-Entwickler-Projekt mit 180 Mitarbeitern im Rücken bedeutet das: Stundenlange Suche, warum der Build auf dem CI-Server plötzlich nicht mehr geht, Frust, und am Ende bleibt man auf der alten Version.

Das ist kein Vorwurf an Lock. Das ist ein strukturelles Problem: KMU-Entwickler haben keinen Puffer für experimentelle Abhängigkeiten. Beta-Pakete sind etwas für Teams, die a) eine Teststufe vor Production haben, b) jemanden, der den Breaking Change triagt, und c) Zeit, das zu tun. Bei Thomas gibt es das alles nicht.


Was empfehle ich konkret?

Wenn du in einer KMU-.NET-Anwendung bist und Enum-Performance ein echtes, gemessenes Problem ist – nicht ein vermutetes –, dann lohnt sich NetEscapades.EnumGenerators. Aber:

Warte auf 1.0.0 stabil. Lock selbst sagt es: Er will die stabile Version bald rausbringen. Genau dafür gibt es die Beta-Phase. Für Produktionssysteme in KMU gilt: keine Beta-Abhängigkeiten außer du weißt genau, was du tust und kannst schnell reagieren.

Miss vorher. Bevor du irgendwas an Enum-Handling änderst, bau dir einen BenchmarkDotNet-Test oder schau dir wenigstens mit dem Profiler an, wo die Zeit wirklich verbracht wird. Ich habe selten einen Fall gesehen, wo ToString() auf einem Enum der tatsächliche Flaschenhals war. Meistens ist es SQL, Netzwerk oder ein ineffizienter Loop dahinter.

Versteh das Paket-Split-Prinzip, auch wenn du das Paket nie nutzt. Was Lock beschreibt – öffentliche Typen in einer DLL, die eigentlich nur Marker-Attribute enthält – ist ein konkreter Fehler, den man selbst machen kann. Wenn du eigene interne NuGet-Pakete baust (und das tun mehr KMU als man denkt, spätestens wenn Code zwischen zwei Projekten geteilt wird), dann ist das ein direkter Lernmoment: Marker-Attribute-Assemblies enthalten keine öffentlichen Domain-Typen. Punkt.

Und wenn du .NET Framework 4.x noch läufst: Das ist kein Makel, aber es ist eine Entscheidung mit einer Uhr daran. Irgendwann wirst du modernisieren müssen – nicht wegen Source Generators, sondern wegen Security-Updates, Vendor-Support-Enden und dem nächsten Entwickler, den du einstellen willst und der Framework 4.6 nicht mehr anfassen möchte. Das ist eine andere Diskussion, aber sie hängt direkt damit zusammen, ob Artikel wie Locks überhaupt für dich relevant werden.


Der vollständige Original-Beitrag von Andrew Lock: Splitting the NetEscapades.EnumGenerators packages: the road to a stable release

Lock schreibt präzise und ohne Aufschneidererei – wenn du .NET-Entwickler bist, ist sein Blog ohnehin Pflichtlektüre. Dieser Beitrag hier ist nur der Versuch, den Kontext zu liefern, der in technisch exzellenten Artikeln oft fehlt: Was macht das mit Entwicklern, die kein Team hinter sich haben?


Wenn du gerade genau in so einer Situation steckst – Legacy-.NET, Performance-Fragen, NuGet-Chaos oder einfach nicht weißt, ob das Problem, das du siehst, das richtige Problem ist: Buch dir 30 Minuten mit mir. Kein Pitch, kein Angebot – nur Klartext.

30 Min Klartext-Sparring

— Bernhard