C# Assembly ohne expliziten Aufruf initialisieren

In bestimmten Situationen ist es notwendig, eine Assembly zu initialisieren. Beispielsweise, um statische Werte zuzuweisen, Überprüfungen durchzuführen oder Schriftarten zu laden. Ein Beispiel wäre der Aufruf von BsonClassMap.RegisterClassMap
aus dem MongoDB SDK oder das Setzen des Werts für QuestPDF.Settings.License
in QuestPDF. Um diese Initialisierung automatisch durchzuführen, kann das Attribut ModuleInitializer
verwendet werden. Dieses Attribut kennzeichnet Methoden, die vor jedem anderen Code (z. B. Typinitialisierer oder statische Konstruktoren) in der gesamten Assembly ausgeführt werden. Es wurde mit C#9 eingeführt. Die Anforderungen an eine solche Initialisierungsmethode sind1:
- Sie muss statisch sein.
- Sie darf keine Parameter haben.
- Sie muss void zurückgeben.
- Sie darf nicht generisch sein.
- Sie darf nicht in einer generischen Klasse enthalten sein.
- Sie muss aus der enthaltenden Assembly zugänglich sein (d. h. die Methode und ihre enthaltende Klasse müssen internal oder public sein).
Das Attribut ModuleInitializer
ermöglicht es somit, Initialisierungsmethoden automatisch aufzurufen, ohne dass ein expliziter Aufruf erforderlich ist.
using System.Runtime.CompilerServices;
class Init
{
[ModuleInitializer]
internal static void Initialisierung()
{
// ...
}
}
Nachteile
Die Verwendung von ModuleInitializer
in C# bietet zwar Vorteile, aber es gibt auch einige Nachteile.
- Nachvollziehbarkeit geht verloren:
- Bei
ModuleInitializer
wird die Assembly initialisiert ohne direkten Aufruf, andere Entwickler können dies nicht direkt einsehen und somit übersehen. - Dies kann die Wartbarkeit und das Debugging erschweren, da es keine klare Stelle im Code gibt, an der die Initialisierung stattfindet.
- Andere Entwickler könnten Schwierigkeiten haben, den Zusammenhang zwischen der automatischen Initialisierung und bestimmten Funktionalitäten zu erkennen.
- Bei
- Keine Parameter:
ModuleInitializer
müssen parameterlos sein. Das bedeutet, dass keine Abhängigkeiten oder Konfigurationsoptionen über Parameter übergeben werden können.- Dependency Injection (DI) ist daher nicht möglich, da keine Parameter zur Verfügung stehen.
- Wenn spezifische Konfigurationsoptionen für die Initialisierung benötigst werden, müssen alternative Ansätze in Betracht gezogen werden.
Es ist wichtig, diese Nachteile abzuwägen und zu entscheiden, ob die Verwendung von ModuleInitializer
in deinem speziellen Fall sinnvoll ist. In einigen Situationen können sie dennoch eine praktische Lösung sein, um bestimmte Aufgaben automatisch auszuführen.