Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Use Reflection.Emit to generate Types that reference each other [duplicate]

I want to generate Types via reflection at runtime that reference each other.

With static code I would do this

public class Order
{
    public int Id { get; set; }
    public Customer Customer { get; set; }
}

public class Customer
{
    public int Id { get; set; }
    public Order Order { get; set; }
}

I can sucessfully generate my Order and my OrderDetails Type with the value type properties.

The code looks like this

var aName = new System.Reflection.AssemblyName("DynamicAssembly");
var ab = AppDomain.CurrentDomain.DefineDynamicAssembly(
    aName, System.Reflection.Emit.AssemblyBuilderAccess.Run);
var mb = ab.DefineDynamicModule(aName.Name);

var tb = mb.DefineType("Order",
    System.Reflection.TypeAttributes.Public, typeof(Object));

var pbId = tb.DefineProperty("Id", PropertyAttributes.None, typeof(int), null);

Now I am stuck at this line:

var pbCustomer = tb.DefineProperty("Customer", PropertyAttributes.None, ???, null);

I am required to pass the type of the property to the DefineProperty method but the type does not exist at this point. Now I could just create a type builder for customer at this point and use tb.CreateType() to get the type but that would not help since Customer needs a reference to Order, too.

like image 624
Jürgen Steinblock Avatar asked Jul 01 '14 15:07

Jürgen Steinblock


1 Answers

Your last paragraph is roughly right, but TypeBuilder derives from Type, so you don't need to call CreateType. That is, create type builders for each of the recursive types, then define the properties passing the respective builders themselves as the return types.

like image 191
kvb Avatar answered Sep 21 '22 00:09

kvb