Frage

Modulinitialisierung ist ein Merkmal der CLR, die in C # oder VB.NET nicht direkt verfügbar sind. Sie sind globale statische Methoden namens .cctor, die vor jedem anderen Code auszuführen garantiert werden (Typ initializers, statische Konstruktoren) in einer Baugruppe ausgeführt werden. Ich wollte dies kürzlich in einem Projekt verwenden und gehackten zusammen meine eigenen Lösung (Konsolenprogramm / msbuild Aufgabe) Mono.Cecil, aber ich habe mich gefragt:

  1. Gibt es eine Möglichkeit, den C # -Compiler in Emissionsmodul Initialisierer zu betrügen? Alle Attribute (zum Beispiel CompilerGenerated, SpecialName) oder andere Tricks, die verwendet werden könnten?

  2. Sie die C # / VB.NET jemals emittieren diese initializers sich für einen bestimmten Zweck? Von dem, was ich gesehen habe sie von Managed C ++ verwendet werden, für einige Interop-Zwecke, aber ich konnte jeden Hinweis auf sie nicht gefunden werden für andere Zwecke verwendet. Irgendwelche Ideen?

War es hilfreich?

Lösung

Nein, es gibt keine Möglichkeit, sie in C # zu emittieren, da C # stellt alles in einer Klasse / Struktur und Modulinitialisierung global sein muß.

Sie haben ein anderes Werkzeug verwenden, um sie zu schreiben, vorzugsweise IL-Assembler.

Was die zweite Frage betrifft, muss ich zugeben, dass ich nicht weiß, aber ich habe nie von C # erzeugt gesehen, und ich verwende ILDasm ziemlich oft, so nehme ich an, dass es ihnen nicht emittieren.

Andere Tipps

Überprüfen Sie das Modul initializer Addon des ehrfürchtigen Open-Source-IL-Weaver-Projekt aus " fody ", geschrieben von Simon Cropp: https://github.com/fody/moduleinit

Es erlaubt Ihnen, ein Verfahren anzugeben, die in eine Montage initializer von fody übersetzt werden:

public static class ModuleInitializer
{
    public static void Initialize()
    {
        //Init code
    }
}

erhält diese:

static <Module>()
{
    ModuleInitializer.Initialize();
}

Vielleicht System.Reflection.Emit Namespace kann Ihnen helfen. MethodAttributes Aufzählung enthält ähnliche Elemente (SpecialName, RTSpecialName).

Einar, Ihre Frage hat noch keinen mir klar, dass Sie bereits ein Tool geschrieben, das ein Modul initializer in eine bereits kompilierte Assembly injizieren kann.

http://einaregilsson.com/module-initializers-in-csharp

habe ich versucht, die Anwendung und es funktioniert perfekt. Wie Sie schreiben, es sollte 2-4,5 mit allen gängigen Frameworks arbeiten.

Es gibt nur ein Problem, dass Ihre Lösung für mich nutzlos macht: Ihre initializer werden aufgerufen, wenn die Anwendung zum ersten Mal etwas in der Versammlung ZUGANG.

Was ich brauche, ist, dass das Modul initializer sofort aufgerufen werden soll, wenn die Versammlung in den Prozess geladen wird. Aber es ist nicht. Wenn also die Anwendung zugreifen nicht die Baugruppe wird es nie initialisiert werden.

Nach einem ganzen Tag der Untersuchung scheint es mir, dass der einzige Weg, dies zu erhalten, ist ein Managed C ++ Assembly zu schreiben und den Code in DllMain () auszuführen.

Wenn Sie statischen Konstruktoren oder Singleton-Klassen, die Sie wahr eine statische Variable C # Compiler zugreifen kann, wird .cctor emittieren.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top