You can create the parent class without creating the child class in a different assembly and in fact your code is close to be correct. In you code you have one mistake in line:
parentBuilder.DefineProperty("MyProperty", PropertyAttributes.None, childBuilder.CreateType(), null);
Here you are trying to CreateType
of nested type, which is unnecessary at this moment. You can provide just a TypeBuilder
for it:
parentBuilder.DefineProperty("MyProperty", PropertyAttributes.None, childBuilder, null);
But remember, that defining a property in such way is not enough. You must provide a implementation for its setter and getter (and probably a backing field). Here you have a working example for generation of class:
public class Parent
{
public class Child
{
}
private Parent.Child myChild;
public Parent.Child MyChild
{
get
{
return this.myChild;
}
set
{
this.myChild = value;
}
}
}
Code:
TypeBuilder parentBuilder = moduleBuilder.DefineType("Parent", TypeAttributes.Public);
TypeBuilder childBuilder = parentBuilder.DefineNestedType("Child", TypeAttributes.NestedPublic);
PropertyBuilder propertyBuilder = parentBuilder.DefineProperty("MyChild", PropertyAttributes.None, childBuilder, null);
// Define field
FieldBuilder fieldBuilder = parentBuilder.DefineField("myChild", childBuilder, FieldAttributes.Private);
// Define "getter" for MyChild property
MethodBuilder getterBuilder = parentBuilder.DefineMethod("get_MyChild",
MethodAttributes.Public | MethodAttributes.SpecialName | MethodAttributes.HideBySig,
childBuilder,
Type.EmptyTypes);
ILGenerator getterIL = getterBuilder.GetILGenerator();
getterIL.Emit(OpCodes.Ldarg_0);
getterIL.Emit(OpCodes.Ldfld, fieldBuilder);
getterIL.Emit(OpCodes.Ret);
// Define "setter" for MyChild property
MethodBuilder setterBuilder = parentBuilder.DefineMethod("set_MyChild",
MethodAttributes.Public | MethodAttributes.SpecialName | MethodAttributes.HideBySig,
null,
new Type[] { childBuilder });
ILGenerator setterIL = setterBuilder.GetILGenerator();
setterIL.Emit(OpCodes.Ldarg_0);
setterIL.Emit(OpCodes.Ldarg_1);
setterIL.Emit(OpCodes.Stfld, fieldBuilder);
setterIL.Emit(OpCodes.Ret);
propertyBuilder.SetGetMethod(getterBuilder);
propertyBuilder.SetSetMethod(setterBuilder);