I need to generate a class using Reflection.Emit that implements the following interface.
public interface IObject
{
T Get<T>(string propertyName);
}
Does anyone have an example of how I would emit the following as a simple test case?
class GeneratedObject : IObject
{
public T Get<T>(string propertyName)
{
// this is the simplest possible implementation
return default(T);
}
}
If you're using Reflection.Emit, you really ought to grab a copy of the Reflection.Emit language add-in for Reflector. While not perfect, it should get you at least 95% of the way to any given emitted code.
I don't have a compiler handy, but something like this should work:
var aName = new AssemblyName("temp");
var appDomain = Threading.Thread.GetDomain();
var aBuilder = appDomain.DefineDynamicAssembly(aName, AssemblyBuilderAccess.Run);
var mBuilder = aBuilder.DefineDynamicModule(aName.Name);
var tBuilder = mBuilder.DefineType("GeneratedObject", TypeAttributes.Public | TypeAttributes.Class);
tBuilder.AddInterfaceImplementation(typeof(IObject));
var methBuilder = tBuilder.DefineMethod("Get", MethodAttributes.Public | MethodAttributes.Final | MethodAttributes.Virtual);
var typeParam = mb.DefineGenericParameters(new string[] { "T" })[0];
methBuilder.SetParameters(new Type[] { typeof(string) });
methBuilder.SetReturnType(typeParam);
var ilg = methBuilder.GetILGenerator();
let lBuilder = ilg.DeclareLocal(typeParam);
ilg.Emit(OpCodes.Ldloca_S, (byte)0);
ilg.Emit(OpCodes.Initobj, typeParam);
ilg.Emit(OpCodes.Ldloc_0);
ilg.Emit(OpCodes.Ret);
var generatedType = tBuilder.CreateType();
I believe AutoMapper and/or LinFu will do this for you. You can definitely create an instance of an interface using AutoMapper, I've done it.
You forgot to BOX the return:
internal delegate object FastConstructorHandler(object[] paramters);
private static FastConstructorHandler CreateDelegate(Type Tipo)
{
DynamicMethod dynamicMethod = new DynamicMethod(string.Empty,
typeof(object), new Type[] { typeof(object[]) }, Tipo.Module, false);
ILGenerator ilg = dynamicMethod.GetILGenerator();
ilg.DeclareLocal(Tipo);
ilg.Emit(OpCodes.Ldloca_S, (byte)0);
ilg.Emit(OpCodes.Initobj, Tipo);
ilg.Emit(OpCodes.Ldloc_0);
ilg.Emit(OpCodes.Box, Tipo);
ilg.Emit(OpCodes.Ret);
return (FastConstructorHandler)dynamicMethod.CreateDelegate(typeof(FastConstructorHandler));
}
It seems, you want to make fast access to object's properties by its name without reflection at run time. Using Yappi and its Property<> class you can implement given interface like this:
class GeneratedObject : IObject
{
public string Value { get { return "Test"; } }
public T Get<T>(string propertyName)
{
return Property<GeneratedObject>.Get<T>(this,propertyName);
}
}
and then use it like this:
IObject obj = new GeneratedObject();
var value = obj.Get<String>("Value"); //value contains "Test"
Do you still need IObject and dynamic type construction?
来源:https://stackoverflow.com/questions/1651455/using-reflection-emit-to-create-a-class-implementing-an-interface