Anwendungsszenarien generieren laut unserem C#-Code dynamisch eine EXE, deren Anwendungsszenarien sehr vielfältig sein können, wie zum Beispiel Softwareautorisierung, man kann die Autorisierungsinformationen eingeben, eine autorisierte DLL generieren usw., also wie man diese Funktion umsetzt? Wir müssen eine technische Emittation erwähnen.
1. Überblick über Emit
Emittieren, kann als emittierend oder erzeugend bezeichnet werden. In Framework existieren Klassen, die mit Emit zusammenhängen, im Grunde unter dem System.Reflection.Emit Namespace. Man sieht, dass Emit als Element der Reflexion existiert. Apropos Reflexion: Jeder sollte damit vertraut sein, es ermöglicht uns, die Elemente der Assembly zu betrachten, um eine große Menge an Informationen zu erhalten, wie zum Beispiel, welche Typen die Assembly enthält, welche Methoden der Typ enthält und so weiter. Aber Reflexionen können nur 'gesehen' werden, während Emit während der Laufzeit dynamisch Code generieren kann. Schauen wir uns an, wie man Code mit Emit generiert.
2. Montage- und verwaltetes Modul
Eine Assembly ist eine logische Gruppierung von einem oder mehreren Modulen, Ressourcendateien, und zweitens ist eine Assembly die kleinste Einheit für Wiederverwendung, Sicherheit und Versionierung. Die DLLs und EXEs, die wir sehen, können als Assembly bezeichnet werden; eine Assembly enthält mehrere Module, aber normalerweise kompilieren wir beim VS-Kompilieren nur ein Modul; wenn wir mehrere Module in einer Assembly kompilieren wollen, müssen wir csc.exe Implementierung verwenden.
3. Codeoperationen dynamisch generieren
Zuerst müssen wir verstehen, mit welchem Typ jeder dynamische Typ in .NET dargestellt wird.
Assembly: System.Reflection.Emit.AssemblyBuilder (definiert und repräsentiert dynamische Assemblies)
Konstruktor: System.Reflection.Emit.ConstructorBuilder (ein Konstruktor, der dynamische Klassen definiert und repräsentiert)
Benutzerdefiniertes Attribut: System.Reflection.Emit.CustomAttributeBuilder (hilft dabei, benutzerdefinierte Attribute mithilfe von vom Konstruktor übermittelten Parametern zu generieren, um Attribute für Klassen zu erzeugen)
Enum: System.Reflection.Emit.EnumBuilder (erklärt und gibt den Enum-Typ an)
Ereignis: System.Reflection.Emit.EventBuilder (Ereignis, das die Klasse definiert)
Feld: System.Reflection.Emit.FieldBuilder (Definiert und repräsentiert Felder.) kann eine solche Klasse nicht erben)
Lokale Variablen: System.Reflection.Emit.LocalBuilder (stellt lokale Variablen innerhalb einer Methode oder eines Konstruktors dar)
Methode: System.Reflection.Emit.MethodBuilder (eine Methode (oder Konstruktor), die eine dynamische Klasse definiert und darstellt)
Modul: System.Reflection.Emit.ModuleBuilder (definiert und repräsentiert Module in dynamischen Assemblies)
Parameter: System.Reflection.Emit.ParameterBuilder (Erstelle oder assoziiere Parameterinformationen wie Methodenparameter, Ereignisparameter usw.)
Eigenschaft: System.Reflection.Emit.PropertyBuilder (Definiere den Eigenschaftstyp)
Klasse: System.Reflection.Emit.TypeBuilder (Definition und Erstellung einer neuen Instanz der Klasse zur Laufzeit)
OpCode ist eine Beschreibung einer Zwischensprache (IL)-Direktive. Dazu gibt es viele Anleitungen, du kannst auf der offiziellen Microsoft-Website nachsehen:Der Hyperlink-Login ist sichtbar.
AssemblyBuilderAccess-Zugriffsbeschränkungen
AssemblyBuilderAccess.Run; Zeigt an, dass die Assembly ausgeführt werden kann, aber nicht gespeichert werden kann. AssemblyBuilderAccess.Save; Zeigt an, dass die Assembly gespeichert, aber nicht ausgeführt werden kann. AssemblyBuilderAccess.RunAndSave; Zeigt an, dass die Assembly gespeichert und ausgeführt werden kann. AssemblyBuilderAccess.ReflectionOnly; Zeigt an, dass Assemblies nur in einem reflektierenden Kontext verwendet werden können und nicht ausgeführt werden können. AssemblyBuilderAccess.RunAndCollect; Zeigt an, dass die Baugruppe entladen und der Speicher zurückgewonnen werden kann.
Der Code lautet wie folgt:
Zuerst verwenden Sie emitt, um IL-Code zu generieren, dann dynamisch eine Assembly zu erzeugen und schließlich die Assembly zu laden und ihre Methoden aufzurufen, wie in der untenstehenden Abbildung gezeigt:
Verwenden Sie ILSpy, um den generierten Code wie im untenstehenden Bild gezeigten Code anzuzeigen:
(Ende)
|