Ich muss eine neue Schnittstelle zur Laufzeit mit allen die gleichen Mitglieder wie eine vorhandene Schnittstelle generieren, mit dem Unterschied, dass ich einige der Methoden (einige von die Attributparameter sind bis zur Laufzeit nicht bekannt). Wie kann es erreicht werden?Mit .NET Reflection.Emit, um eine Schnittstelle zu generieren
7
A
Antwort
8
Ihre Frage ist nicht sehr spezifisch. Wenn Sie es mit mehr Informationen aktualisieren, werde ich diese Antwort mit zusätzlichen Details ausfüllen.
Hier finden Sie eine Übersicht der manuellen Schritte.
- eine Baugruppe mit DefineDynamicAssembly erstellen
- erstellen Modul mit DefineDynamicModule
- den Typ mit DefineType erstellen. Übergeben Sie
TypeAttributes.Interface
, um Ihren Typ zu einer Schnittstelle zu machen. - Iterieren Sie über die Elemente in der ursprünglichen Schnittstelle, und erstellen Sie ähnliche Methoden in der neuen Schnittstelle, und wenden Sie bei Bedarf Attribute an.
- Rufen Sie
TypeBuilder.CreateType
, um das Erstellen Ihrer Schnittstelle abzuschließen.
12
Um dynamisch eine Baugruppe mit einer Schnittstelle zu erstellen, die Attribute:
using System.Reflection;
using System.Reflection.Emit;
// Need the output the assembly to a specific directory
string outputdir = "F:\\tmp\\";
string fname = "Hello.World.dll";
// Define the assembly name
AssemblyName bAssemblyName = new AssemblyName();
bAssemblyName.Name = "Hello.World";
bAssemblyName.Version = new system.Version(1,2,3,4);
// Define the new assembly and module
AssemblyBuilder bAssembly = System.AppDomain.CurrentDomain.DefineDynamicAssembly(bAssemblyName, AssemblyBuilderAccess.Save, outputdir);
ModuleBuilder bModule = bAssembly.DefineDynamicModule(fname, true);
TypeBuilder tInterface = bModule.DefineType("IFoo", TypeAttributes.Interface | TypeAttributes.Public);
ConstructorInfo con = typeof(FunAttribute).GetConstructor(new Type[] { typeof(string) });
CustomAttributeBuilder cab = new CustomAttributeBuilder(con, new object[] { "Hello" });
tInterface.SetCustomAttribute(cab);
Type tInt = tInterface.CreateType();
bAssembly.Save(fname);
Das schafft folgendes:
namespace Hello.World
{
[Fun("Hello")]
public interface IFoo
{}
}
Hinzufügen von Methoden verwenden, um die Method Klasse durch Aufruf TypeBuilder.DefineMethod.
Nein, das ist cool. Ich musste Reflection.Emit vorher nicht verwenden, also wollte ich nur sehen, ob irgendjemand einen Stolperstein in meinem bösen Masterplan entdecken könnte. –