14

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);
    }
}
0

5 Answers 5

6

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.

Sign up to request clarification or add additional context in comments.

1 Comment

-1 While the add-in may be (or may be not, I don't know nor care, I don't use Reflector, it's expensive) extremely useful, this does not answer the question.
4

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();

2 Comments

Hello, i have used your example successfully (minor code edits). After i create the generatedType, i use Activator.CreateInstance(generatedType) to get a hold on the object. I cast it as the interface IObject, and then i call the method. Indeed, it gives me default(T). What i require is to change that implementation, and instead of giving me default(T), to hook in with a generic method that receives those parameters (or the list of parameters) and gives a proper implementation. Any idea on how to achieve that?
@Darksody - Sorry, I can't tell from your description exactly what you mean. It would probably be best to open a new question that clearly lays out the specifics.
0

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.

5 Comments

AutoMapper is so slow!
That's a pretty broad statement with no context. ymmv and it depends on your usage. ericlippert.com/2012/12/17/performance-rant
You can do simple test over 100000 items in array. If you write it whithout automap it will be 10 times faster. For small set i belive this difference doesn't matter...
But performance bottlenecks is not only abot specific line of code. Imagibe when some method where that line of code is executed very frequently then Im sure you would consider changing the way how it is implemented ;)
did you look at the article I linked at all?
0

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));
    }

Comments

0

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?

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.