title: C# TypeBuilder Generate Class with Function Dynamically
body: <p>I'm trying to use TypeBuilder in C# to dynamically generate a class with a function, and to have that function call another base function.</p>
  
  <p>The reason for the need for this is that in Revit application development, every button needs to have a class that implements IExternalCommand with an Execute function. I'd like to dynamically create buttons and handle their execution at runtime based on their ID, so I therefore need to dynamically create the classes too.</p>
  
  <p>Hopefully this code gets across what I'm looking for ( or here <a href="http://pastebin.com/eehGKteT" rel="nofollow">http://pastebin.com/eehGKteT</a> ):</p>
  
  <pre><code>using Autodesk.Revit.DB;
  using Autodesk.Revit.UI;
  
  using System;
  using System.Collections.Generic;
  using System.Linq;
  using System.Text;
  using System.Threading.Tasks;
  using System.Reflection;
  using System.Reflection.Emit;
  
  namespace Centek_Revit_Addin
  {
      class DynamicButton
      {
          // I would like to use a function like this to generate the class during runtime, presumably using TypeBuilder:
          public static void generateClass(int id)
          {
              // ... Code which would generate a class with the name "GeneratedClass" with the 'id' parameter appended at the end
              // ... The class implements IExternalCommand
              // ... The class has an Execute function with the parameters listed in the example, which returns a call to the Execute function in DynamicButton
              //      along with the added integer 'id' parameter at the end
          }
  
          public static Autodesk.Revit.UI.Result Execute(ExternalCommandData revit, ref string message, ElementSet elements, int id)
          {
              TaskDialog.Show("About", "ID of the class that called us: " + id);
              return Autodesk.Revit.UI.Result.Succeeded;
          }
      }
  
  
      // ===== This class would have been generated during runtime using generateClass(15) ====== //
      class GeneratedClass15 : Autodesk.Revit.UI.IExternalCommand
      {
          public Autodesk.Revit.UI.Result Execute(Autodesk.Revit.UI.ExternalCommandData revit, ref string message, Autodesk.Revit.DB.ElementSet elements)
          {
              return DynamicButton.Execute(revit, ref message, elements, 15);
          }
      }
      // =================================================================== //
  }
  </code></pre>
  
  <p>I tried to get a TypeBuilder working and I figured out the basics but I just can't seem to figure out how to use to Opcodes to get the class how I'd like it.</p>
  
  <p>So basically I am looking for help writing the generateClass(int id) function. Any help would be HUGELY appreciated!</p>
  
  <p>EDIT:</p>
  
  <pre><code>I would like to add my progress:
  using Autodesk.Revit.DB;
  using Autodesk.Revit.UI;
  
  using System;
  using System.Collections.Generic;
  using System.Linq;
  using System.Text;
  using System.Threading.Tasks;
  using System.Reflection;
  using System.Reflection.Emit;
  
  namespace Centek_Revit_Addin
  {
      class DynamicButton
      {
          // I would like to use a function like this to generate the class during runtime, presumably using TypeBuilder:
          public static void generateClass(int id)
          {
              // ... Code which would generate a class with the name "GeneratedClass" with the 'id' parameter appended at the end
              // ... The class implements IExternalCommand
              // ... The class has an Execute function with the parameters listed in the example, which returns a call to the Execute function in DynamicButton
              //      along with the added integer 'id' parameter at the end
  
              AssemblyName aName = new AssemblyName("DynamicAssemblyExample");
              AssemblyBuilder ab = AppDomain.CurrentDomain.DefineDynamicAssembly(aName, AssemblyBuilderAccess.RunAndSave);
  
              // For a single-module assembly, the module name is usually 
              // the assembly name plus an extension.
              ModuleBuilder mb = ab.DefineDynamicModule(aName.Name, aName.Name + ".dll");
  
              // Create class which extends Object and implements IExternalCommand
              Type[] implements = {typeof(IExternalCommand)};
              TypeBuilder tb = mb.DefineType("GeneratedClass" + id, TypeAttributes.Public, typeof(Object), implements);
  
  
              // Create 'Execute' function sig
              Type[] paramList = {typeof(ExternalCommandData), typeof(string), typeof(ElementSet)};
              MethodBuilder mbExecute = tb.DefineMethod("Execute", MethodAttributes.Public, typeof(Result), paramList);
  
              // Create 'Execute' function body
              ILGenerator ilGen = mbExecute.GetILGenerator();
  
              ilGen.Emit(OpCodes.Nop);
              ilGen.Emit(OpCodes.Ldarg_1);
              ilGen.Emit(OpCodes.Ldarg_2);
              ilGen.Emit(OpCodes.Ldarg_3);
  
              ilGen.Emit(OpCodes.Ldc_I4_S, id);
  
              Type[] paramListWID = { typeof(ExternalCommandData), typeof(string), typeof(ElementSet), typeof(int) };
              ilGen.EmitCall(OpCodes.Call, typeof(DynamicButton).GetMethod("Execute"), paramListWID);
  
  
              //ilGen.Emit(OpCodes.Ret);
  
  
              tb.CreateType();
          }
  
          public static Autodesk.Revit.UI.Result Execute(ExternalCommandData revit, ref string message, ElementSet elements, int id)
          {
              TaskDialog.Show("About", "ID of the class that called us: " + id);
              return Autodesk.Revit.UI.Result.Succeeded;
          }
      }
  
  
  
      // ===== This class would have been generated during runtime using generateClass(15) ====== //
      class GeneratedClass15 : Autodesk.Revit.UI.IExternalCommand
      {
          public Autodesk.Revit.UI.Result Execute(Autodesk.Revit.UI.ExternalCommandData revit, ref string message, Autodesk.Revit.DB.ElementSet elements)
          {
              return DynamicButton.Execute(revit, ref message, elements, 15);
          }
      }
      // =================================================================== //
  }
  </code></pre>
  
  <p>This code is much closer, but when running it I get the error</p>
  
  <blockquote>
    <p>System.TypeLoadException: Method 'Execute' in type 'GeneratedClass99'
    from assembly 'DynamicAssemblyExample, Version=0.0.0.0,
    Culture=neutral, PublicKeyToken=null' does not have an implementation.</p>
  </blockquote>
  
  <p>This error occurs when I call <code>CreateType</code>(..) in <code>generateClass</code>(..)</p>