I have some very simple code to generate an assembly and invoke a method on a contained type. The method gets called and runs correctly, however when I view the generated assembly using Reflector, I don’t see the type.
Below is the sample code:
namespace ConsoleApplication2 { class Proggy { public static void Main(string[] args) { var ab = AppDomain.CurrentDomain.DefineDynamicAssembly( new AssemblyName() { Name = 'MyAssembly' }, AssemblyBuilderAccess.RunAndSave); var module = ab.DefineDynamicModule(ab.GetName().Name); var typeBuilder = module.DefineType('MyType'); var ctr = typeBuilder.DefineConstructor(MethodAttributes.Public, CallingConventions.Standard, Type.EmptyTypes); var ilgc = ctr.GetILGenerator(); ilgc.Emit(OpCodes.Ldarg_0); ilgc.Emit(OpCodes.Call, typeof(object).GetConstructor(Type.EmptyTypes)); ilgc.Emit(OpCodes.Ret); var method = typeBuilder.DefineMethod('MyMethod', MethodAttributes.Public, typeof(int), new[] { typeof(string) }); var ilg = method.GetILGenerator(); ilg.Emit(OpCodes.Ldarg_1); ilg.EmitCall(OpCodes.Callvirt, typeof(string).GetProperty('Length').GetGetMethod(), null); ilg.Emit(OpCodes.Ret); var type = typeBuilder.CreateType(); ab.Save('mytestasm.dll'); var inst = Activator.CreateInstance(type); Console.WriteLine(type.InvokeMember('MyMethod', BindingFlags.InvokeMethod, null, inst, new[] { 'MyTestString' })); Console.ReadLine(); } } }
and here is the corresponding disassembly from Reflector:
.assembly MyAssembly { .ver 0:0:0:0 .hash algorithm 0x00008004 } .module RefEmit_OnDiskManifestModule // MVID: {0B944140-58D9-430E-A867-DE0AD0A8701F} // Target Runtime Version: v2.0.50727
… and …
{ .class private auto ansi <Module> { } }
Can anyone help me with getting the assembly properly saved?
The trick is to use a ‘persistable module’ version of DefineDynamicModule method on the AssemblyBuilder instance. That is, instead of:
use something like:
Thereafter the corresponding module appears in the assembly after saving.