Using Reflection Emit and Creating Instances

Tech-Archive recommends: Fix windows errors by optimizing your registry



I am trying to use the Reflection Emit capability of the framework to
dynamically inherit a base class. I want to call the base classes constructor
with arguments passed into the new classes constructor. I think I am close,
but get the following error trying to activate the new class.


System.Reflection.TargetInvocationException was unhandled
Message="Exception has been thrown by the target of an invocation."
Source="mscorlib"
StackTrace:
at System.RuntimeMethodHandle._InvokeConstructor(Object[] args,
SignatureStruct& signature, IntPtr declaringType)
at System.RuntimeMethodHandle.InvokeConstructor(Object[] args,
SignatureStruct signature, RuntimeTypeHandle declaringType)
at System.Reflection.RuntimeConstructorInfo.Invoke(BindingFlags
invokeAttr, Binder binder, Object[] parameters, CultureInfo culture)
at System.RuntimeType.CreateInstanceImpl(BindingFlags bindingAttr,
Binder binder, Object[] args, CultureInfo culture, Object[]
activationAttributes)
at System.Activator.CreateInstance(Type type, BindingFlags
bindingAttr, Binder binder, Object[] args, CultureInfo culture, Object[]
activationAttributes)
at System.Activator.CreateInstance(Type type, BindingFlags
bindingAttr, Binder binder, Object[] args, CultureInfo culture)
at ReflectionEmit.Program.Main(String[] args) in C:\Documents and
Settings\jmcmeni\Desktop\ReflectionEmit\ReflectionEmit\Program.cs:line 47
at System.AppDomain._nExecuteAssembly(Assembly assembly, String[] args)
at System.AppDomain.ExecuteAssembly(String assemblyFile, Evidence
assemblySecurity, String[] args)
at Microsoft.VisualStudio.HostingProcess.HostProc.RunUsersAssembly()
at System.Threading.ThreadHelper.ThreadStart_Context(Object state)
at System.Threading.ExecutionContext.Run(ExecutionContext
executionContext, ContextCallback callback, Object state)
at System.Threading.ThreadHelper.ThreadStart()
InnerException: System.InvalidProgramException
Message="Common Language Runtime detected an invalid program."
Source="Test"
StackTrace:
at AmericanCar..ctor(String , String )
InnerException:


Here is the small sample that I'm trying to get to work.

Any help would be great.

thanks

Joe

Program



using System;
using System.Reflection;
using System.Reflection.Emit;
using System.Threading;

namespace ReflectionEmit
{
class Program
{
static void Main(string[] args)
{
AssemblyName assemblyName = new AssemblyName();
assemblyName.Name = "Test";
AssemblyBuilder assemblyBuilder =
Thread.GetDomain().DefineDynamicAssembly(assemblyName,
AssemblyBuilderAccess.RunAndSave);
ModuleBuilder module;
module = assemblyBuilder.DefineDynamicModule("Test.dll");

// create a new type to hold our Main method
TypeBuilder typeBuilder = module.DefineType("AmericanCar",
TypeAttributes.Public | TypeAttributes.Class, typeof(Car));


typeBuilder.DefineDefaultConstructor(MethodAttributes.Public);
FieldBuilder fb = typeBuilder.DefineField("brand",
typeof(string), FieldAttributes.Private);

ConstructorInfo ci = typeof(Car).GetConstructor(new Type[] {
typeof(string) });

ConstructorBuilder cb = typeBuilder.DefineConstructor(
ci.Attributes,
ci.CallingConvention, new Type[] { typeof(string),
typeof(string) });

ILGenerator il = cb.GetILGenerator();

int paramCount = ci.GetParameters().Length;
il.Emit(OpCodes.Ldarg_0);
for (int i = 1; i <= paramCount; i++)
{
il.Emit(OpCodes.Ldarg_S, i);
}
il.Emit(OpCodes.Call, ci);

il.Emit(OpCodes.Ldarg_0);
il.Emit(OpCodes.Ldarg_2);
il.Emit(OpCodes.Stfld, fb);

Type type = typeBuilder.CreateType();
assemblyBuilder.Save("Test.dll");

object o = Activator.CreateInstance(type,
BindingFlags.CreateInstance, null, new object[]{"Red","Corvette"},
System.Globalization.CultureInfo.CurrentCulture);

}

}

public class Car
{
private string color;

public string Color
{
get { return color; }
set { color = value; }
}

public Car() { }

public Car(string color)
{
this.color = color;
}
}
}


.



Relevant Pages

  • RE: Using Reflection Emit and Creating Instances
    ... After creating the constructor and Emitting ... at System.RuntimeMethodHandle._InvokeConstructor(Objectargs, ... at System.AppDomain._nExecuteAssembly(Assembly assembly, String[] args) ... AssemblyName assemblyName = new AssemblyName; ...
    (microsoft.public.dotnet.framework.clr)
  • Reflection.Emit usage
    ... class TemplateOne ... public void PrintTemplateOne() ... static void Main(stringargs) ... AssemblyName newAssemName = new ...
    (microsoft.public.dotnet.languages.csharp)
  • Reflection.Emit usage
    ... class TemplateOne ... public void PrintTemplateOne() ... static void Main(stringargs) ... AssemblyName newAssemName = new ...
    (microsoft.public.dotnet.general)
  • CustomAttributeBuilder and Regex.CompileToAssembly()
    ... I am trying to create an assembly to store compiled regular expressions. ... AssemblyName an = new AssemblyName; ... args); ...
    (microsoft.public.dotnet.languages.csharp)