title: Using AssemblyBuilder to build a complex type
body: <p>I have been working on <a href="https://github.com/amir734jj/CustomTypeBuilder/blob/master/CustomTypeBuilder/CustomTypeGenerator.cs" rel="nofollow noreferrer">small library to build very simple types dynamically using <code>AssemblyBuilder</code></a>. I can build a type, add properties into it. But the problem I am facing is adding a property given a dynamically generated type that was also generated using this simple library. In other works, creating a complex type. I tried adding namespace to the type, but I think the source of my problem is not importing the nested type while creating the parent type.</p>
  
  <p>How I create the type and nested type:</p>
  
  <pre><code>var token = "TestNameSpace";
  var nestedType = Builders.CustomTypeBuilder.New(@namespace: token).AddProperty&lt;string&gt;("NestedProp").Compile();
  
  var propertyName = "NestedProp";
  var obj = Builders.CustomTypeBuilder.NewExtend&lt;DummyClass&gt;(@namespace: token)
      .AddProperty(propertyName, nestedType)
      .Instantiate&lt;DummyClass&gt;();
  </code></pre>
  
  <p>The nested type (or <code>NestedProp</code>) is kind of <code>undefined</code> ("Unresolved ...").</p>
  
  <p><a href="https://i.stack.imgur.com/On1rF.png" rel="nofollow noreferrer"><img src="https://i.stack.imgur.com/On1rF.png" alt="enter image description here"></a></p>
  
  <p>The main logic behind the library:</p>
  
  <pre><code>using System;
  using System.Collections.Generic;
  using System.Linq;
  using System.Reflection;
  using System.Reflection.Emit;
  using CustomTypeBuilder.Extensions;
  using static CustomTypeBuilder.Utilities.TypeUtility;
  
  namespace CustomTypeBuilder
  {
      /// &lt;summary&gt;
      /// Creates a new type dynamically
      /// &lt;/summary&gt;
      public class CustomTypeGenerator
      {
          private readonly TypeBuilder _typeBuilder;
  
          private readonly Dictionary&lt;string, Type&gt; _properties;
  
          /// &lt;summary&gt;
          /// Initialize custom type builder
          /// &lt;/summary&gt;
          /// &lt;param name="name"&gt;&lt;/param&gt;
          /// &lt;param name="parentType"&gt;&lt;/param&gt;
          /// &lt;param name="namespace"&gt;&lt;/param&gt;
          public CustomTypeGenerator(string name = null, Type parentType = null, string @namespace = null)
          {
              var assemblyName = RandomSafeString("DynamicAseembly");
              var typeSignature = name ?? RandomSafeString("DynamicType");
  
              // add namespace
              if (@namespace != name)
              {
                  typeSignature = $"{@namespace}.{typeSignature}";
              }
  
              var assemblyBuilder = AssemblyBuilder.DefineDynamicAssembly(new AssemblyName(assemblyName), AssemblyBuilderAccess.Run);
              var moduleBuilder = assemblyBuilder.DefineDynamicModule(RandomSafeString("Module"));
              _typeBuilder = moduleBuilder.DefineType(typeSignature,
                  TypeAttributes.Public |
                  TypeAttributes.Class |
                  TypeAttributes.AutoClass |
                  TypeAttributes.AnsiClass |
                  TypeAttributes.BeforeFieldInit |
                  TypeAttributes.AutoLayout,
                  parentType);
  
              _typeBuilder.DefineDefaultConstructor(MethodAttributes.Public | MethodAttributes.SpecialName | MethodAttributes.RTSpecialName);
  
              _properties = new Dictionary&lt;string, Type&gt;();
          }
  
          /// &lt;summary&gt;
          /// Add attribute to the class
          /// &lt;/summary&gt;
          /// &lt;param name="attribute"&gt;&lt;/param&gt;
          public void AddAttribute(Attribute attribute)
          {
              _typeBuilder.SetCustomAttribute(attribute.BuildCustomAttribute());
          }
  
          /// &lt;summary&gt;
          /// Compile the type builder to a type
          /// &lt;/summary&gt;
          /// &lt;returns&gt;&lt;/returns&gt;
          public Type CompileResultType()
          {            
              return _typeBuilder.CreateType();
          }
  
          /// &lt;summary&gt;
          /// Add interfaces to a type
          /// &lt;/summary&gt;
          /// &lt;param name="type"&gt;&lt;/param&gt;
          public void AddInterface(Type type)
          {
              if (!type.IsInterface)
              {
                  throw new ArgumentException("Type was expected to be an interface");
              }
  
              _typeBuilder.AddInterfaceImplementation(type);
  
              // add types in interface
              type.GetProperties().ForEach(x =&gt; AddProperty(x.Name, x.PropertyType));
          }
  
          public void ExtendType(Type type)
          {
              _typeBuilder.SetParent(type);
          }
  
          public void AddProperty(string propertyName, Type propertyType)
          {
              if (!IsValidName(propertyName)) throw new ArgumentException("Property name does not follow to C# type system");
  
              if (_properties.Keys.Any(x =&gt; x == propertyName)) throw new ArgumentException("Duplicate property name");
  
              // add property to dictionary
              _properties.Add(propertyName, propertyType);
  
              var fieldBuilder = _typeBuilder.DefineField("_" + propertyName, propertyType, FieldAttributes.Private);
  
              var propertyBuilder = _typeBuilder.DefineProperty(propertyName, PropertyAttributes.HasDefault, propertyType, null);
              var getPropMthdBldr = _typeBuilder.DefineMethod("get_" + propertyName,
                  MethodAttributes.Public | MethodAttributes.SpecialName | MethodAttributes.HideBySig, propertyType,
                  Type.EmptyTypes);
              var getIl = getPropMthdBldr.GetILGenerator();
  
              getIl.Emit(OpCodes.Ldarg_0);
              getIl.Emit(OpCodes.Ldfld, fieldBuilder);
              getIl.Emit(OpCodes.Ret);
  
              var setPropMthdBldr = _typeBuilder.DefineMethod("set_" + propertyName,
                      MethodAttributes.Public |
                      MethodAttributes.SpecialName |
                      MethodAttributes.HideBySig,
                      null, new[] {propertyType});
  
              var setIl = setPropMthdBldr.GetILGenerator();
              var modifyProperty = setIl.DefineLabel();
              var exitSet = setIl.DefineLabel();
  
              setIl.MarkLabel(modifyProperty);
              setIl.Emit(OpCodes.Ldarg_0);
              setIl.Emit(OpCodes.Ldarg_1);
              setIl.Emit(OpCodes.Stfld, fieldBuilder);
  
              setIl.Emit(OpCodes.Nop);
              setIl.MarkLabel(exitSet);
              setIl.Emit(OpCodes.Ret);
  
              propertyBuilder.SetGetMethod(getPropMthdBldr);
              propertyBuilder.SetSetMethod(setPropMthdBldr);
          }
      }
  }
  </code></pre>
  
  <p>Any help would be appreciated. Thank you.</p>