Stijn Bernards
Stijn Bernards

Reputation: 1091

MethodBuilder ILGenerator get class property

I'm trying to acces the property of the class my Methodbuilder method is being defined in. This is my current code:

Type[] types = { typeof(HttpListenerContext) };
TypeBuilder tb = GetTypeBuilder(type.Name);
ConstructorBuilder constructor = tb.DefineDefaultConstructor(MethodAttributes.Public | MethodAttributes.SpecialName | MethodAttributes.RTSpecialName);
MethodBuilder mB = tb.DefineMethod("Init", MethodAttributes.Public | MethodAttributes.Virtual, null, types);
ILGenerator il = mB.GetILGenerator();

il.Emit(OpCodes.Ldstr, typeof(Page).GetProperty("_POST").GetValue(??));
il.Emit(OpCodes.Call, typeof(DataSet).GetMethod("SetData"));
il.Emit(OpCodes.Ret);

tb.DefineMethodOverride(mB, typeof(Page).GetMethod("Init"));

try
{
    Type tc = tb.CreateType();
    Page test = (Page)Activator.CreateInstance(tc);
    test.Init();
}
catch (Exception e)
{
    Console.WriteLine(e.Message);
}

This is is class I'm trying to get the property from:

public class Page
{
    public Dictionary<string, string> _POST { get; set; }
    public Dictionary<string, string> _GET { get; set; }
    public Head Headers { get; set; }
    public string ContentType { get; set; }
    public int StatusCode = 200;

    public virtual void Init(HttpListenerContext ctx = null) { }

    public virtual void Load() { }

    public virtual string Send() { return ""; }
    public virtual string Send(string response) { return ""; }
}

The current typebuilder has Page as parent, how can I get a nonstatic value set in my typebuilder class? Like how could I get my method to Console.WriteLine the value of _POST?

private TypeBuilder GetTypeBuilder(string name)
{
     string typeSignature = name;
     AssemblyName aN = new AssemblyName(typeSignature);
     AssemblyBuilder aB = AppDomain.CurrentDomain.DefineDynamicAssembly(aN, AssemblyBuilderAccess.Run);
     ModuleBuilder mB = aB.DefineDynamicModule("MainModule");
     TypeBuilder tB = mB.DefineType(typeSignature + "h",
     TypeAttributes.Public |
     TypeAttributes.Class |
     TypeAttributes.AutoClass |
     TypeAttributes.AnsiClass |
     TypeAttributes.BeforeFieldInit |
     TypeAttributes.AutoLayout,
     typeof(Page));

     return tB;
}


    ILGenerator il = mB.GetILGenerator();

    il.Emit(OpCodes.Ldarg_0);
    il.Emit(OpCodes.Ldstr, typeof(Page).GetProperty("ContentType").GetGetMethod());
    il.Emit(OpCodes.Call, typeof(Console).GetMethod("WriteLine", new Type[] { typeof(string) }));
    il.Emit(OpCodes.Ret);

    tb.DefineMethodOverride(mB, typeof(Page).GetMethod("Init"));

I'm setting the value of ContentType before I'm getting it with my function.

Upvotes: 1

Views: 735

Answers (1)

Luaan
Luaan

Reputation: 63772

It seems like you're creating an instance method on a type that inherits from Page. If that's the case, this is the code you want:

il.Emit(OpCodes.Ldarg_0);  // Load the this reference
il.Emit(OpCodes.Call, typeof(Page).GetProperty("_POST").GetGetMethod());

Also, note that DataSet doesn't have a SetData method - if that's an extension method, you need to use the real type where it's defined rather than DataSet.

Upvotes: 1

Related Questions