Laden...

Source Code Generatoren: Basisnamespace einer Class Library ermitteln

Erstellt von Papst vor 2 Jahren Letzter Beitrag vor 2 Jahren 510 Views
P
Papst Themenstarter:in
441 Beiträge seit 2014
vor 2 Jahren
Source Code Generatoren: Basisnamespace einer Class Library ermitteln

Hi,

ich erstelle gerade einen ISourceGenerator und möchte diesen nicht nur in Projekten mit Main Methode, sondern auch in Klassenbibliotheken einsetzen.
Der Generator erstellt eine Erweiterungsmethode in einer eigenen Klasse für den DI Registrar. Als Namespace möchte ich gerne den Basisnamespace der Lib einsetzen, damit die Erweiterungsmethode direkt verfügbar ist.

In ausführbaren Projekten erhält man den Namespace der Main Methode relativ simpel über


baseNamespace = context.Compilation.GetEntryPoint(context.CancellationToken)?.ContainingNamespace.ToDisplayString();

In einer Klassenbibliothek ist die Rückgabe von GetEntryPoint() allerdings null. Dort behelfe ich mir mit


baseNamespace = context.Compilation.Assembly.MetadataName;

Das ist nicht optimal, denn dieser kann anders sein - sagt schon der Kommentar. Die Property Name ist mit ähnlichen Einschränkungen belegt.
Ich hatte überlegt einfach die Namespaces durchzugehen und aneinanderzusetzen und zu schauen ab wann ich das erste mal eine Typdefinition finde - das finde ich allerdings unsauber (Namespace Parts in der Assembly erhält man via context.Compilation.Assembly.NamespaceNames).

Irgendwie fehlt mir die saubere Lösung.

P
Papst Themenstarter:in
441 Beiträge seit 2014
vor 2 Jahren

Oh cool.. das ist eine gute Quelle für Lösungen, die ich bei mir noch unschön finde.

Problem an der Namespace Lösung bei Refit ist, dass ich ein INamedTypeSymbol bräuchte... ich könnte halt irgendeins nehmen oder das, was den kürzesten Namespace Namen hat.
Schade, dass der Default Namespace kein Teil der Kompilierung ist, nur Teil des Projektes 🙂

P
Papst Themenstarter:in
441 Beiträge seit 2014
vor 2 Jahren

Das kannte ich schon, aber das hilft tatsächlich.

Ich hole mir einfach alle namespaces aller Klassen und nehme den kürzesten.
Alternativ: mit einem eigenen Namespace arbeiten.

Besten Dank!

2.078 Beiträge seit 2012
vor 2 Jahren

Ich denke, ich habe gefunden, was Du suchst.

Nutz den IIncrementalGenerator und nicht den ISourceGenerator.
Den Hauptgrund für dessen Existenz und eine grobe Einführung kannst Du hier nachlesen.
Die Nutzung ist deutlich anders, im Vergleich zur ersten Variante, aber da findest Du dich schon rein 🙂
Ob es das Gleiche auch in der ersten Variante gibt, weiß ich nicht, aber aus den im Artikel beschriebenen Gründen sollte man den sowieso nicht mehr benutzen.

Mir geht's um den AnalyzerConfigOptionsProvider bzw. die GlobalOptions, denn die liefern mir unter Anderem auch folgenden Eintrag:

build_property.rootnamespace = ConsoleApp1

Damit solltest Du haben, was Du suchst 🙂

P
Papst Themenstarter:in
441 Beiträge seit 2014
vor 2 Jahren

Das klingt ganz gut.. ist aber etwas komplexer in der Umsetzung als der ISourceGenerator.

Vielen Dank - schaue ich mir mal an

2.078 Beiträge seit 2012
vor 2 Jahren

Der ISourceGenerator ist ein Auslaufmodell, weil er Performance so extrem schwer macht.
Aber ja, ist komplexer, doch sobald man begriffen hat, was das Konzept ist, geht's eigentlich ganz gut.

Mit dem CompilerVisibleProperty-Item kann man auch weitere Properties sichtbar machen.
Mit dem CompilerVisibleItemMetadata-Item geht das gleiche mit Items, allerdings ist das (noch?) auf "AdditionalFiles" begrenzt. Allerdings sind die Metadaten frei wählbar, man kann also alle beliebigen Items in die AdditionalFiles schreiben und anschließend mit passend definierten Metadaten unterscheiden. Mehr dazu hier, der Artikel ist nicht mehr aktuell, aber das Konzept ist ähnlich.