Erstellen von Methode dynamisch und Ausführung

Hintergrund:

Möchte ich definieren, paar static Methoden in C# , und erzeugen von IL code als byte-array, das aus einer dieser Methoden, die zur Laufzeit ausgewählt (auf dem client), und senden das byte-array über ein Netzwerk zu einem anderen Computer (server), wo es ausgeführt werden soll, nach der erneuten Generierung des IL-Codes, der aus dem byte-array.

Mein Versuch: (POC)

public static class Experiment
{
    public static int Multiply(int a, int b)
    {
        Console.WriteLine("Arguments ({0}, {1})", a, b);
        return a * b;
    }
}

Und dann bekomme ich den IL-code der Methode Körper, als:

BindingFlags flags = BindingFlags.Public | BindingFlags.Static;
MethodInfo meth = typeof(Experiment).GetMethod("Multiply", flags);
byte[] il = meth.GetMethodBody().GetILAsByteArray();

Bisher habe ich nicht alles erstellen dynamisch. Aber ich habe IL-code als byte-array und ich möchte, um eine Baugruppe zu erstellen, dann ein Modul, dann ein Typ, der dann eine Methode - alle dynamisch. Bei der Erstellung der Methode, die Körper der dynamisch erstellten Methode, die ich verwenden den IL-code, die ich mit der spiegelung in den obigen code.

Code generation-code ist wie folgt:

AppDomain domain = AppDomain.CurrentDomain;
AssemblyName aname = new AssemblyName("MyDLL");
AssemblyBuilder assemBuilder = domain.DefineDynamicAssembly(
                                               aname, 
                                               AssemblyBuilderAccess.Run);

ModuleBuilder modBuilder = assemBuilder.DefineDynamicModule("MainModule");

TypeBuilder tb = modBuilder.DefineType("MyType", 
                            TypeAttributes.Public | TypeAttributes.Class);

MethodBuilder mb = tb.DefineMethod("MyMethod", 
     MethodAttributes.Static | MethodAttributes.Public, 
     CallingConventions.Standard,
     typeof(int),                          //Return type
     new[] { typeof(int), typeof(int) });  //Parameter types

mb.DefineParameter(1, ParameterAttributes.None, "value1");  //Assign name 
mb.DefineParameter(2, ParameterAttributes.None, "value2");  //Assign name 

//using the IL code to generate the method body
mb.CreateMethodBody(il, il.Count()); 

Type realType = tb.CreateType();

var meth = realType.GetMethod("MyMethod");
try
{
    object result = meth.Invoke(null, new object[] { 10, 9878 });
    Console.WriteLine(result);  //should print 98780 (i.e 10 * 9878)
}
catch (Exception e)
{
    Console.WriteLine(e.ToString());
}

Aber statt Druck 98780 auf der Ausgabe-Fenster, wirft er eine exception, die sagen,

System.Reflexion.TargetInvocationException: Ausnahme wurde ausgelöst durch das Ziel für einen Aufruf. ---> System.TypeLoadException: Konnte nicht geladen werden Typ 'Invalid_Token.0x0100001E' aus assembly 'MyDLL, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null".

     bei MyType.MyMethod(Int32 Wert1, Int32 Wert2)
[...]

Bitte helfen Sie mir herauszufinden, die Ursache des Fehlers, und wie es zu lösen ist.

  • Sie können möglicherweise verwenden Sie Mono.Cecil für einige Sachen.
  • Warum nicht die standard-Methode mit den plugins??? Ich meine zu definieren Schnittstelle für plugin und senden Sie die dll mit der Umsetzung für Ihre Anwendung nach dem laden der dll und der code ausgeführt.
InformationsquelleAutor Nawaz | 2011-10-06
Schreibe einen Kommentar