<?xml version="1.0" encoding="UTF-8"?>
<rss xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns:taxo="http://purl.org/rss/1.0/modules/taxonomy/" version="2.0">
  <channel>
    <title>topic Re: Create Dynamic IExternalCommand class at runtime in Revit API Forum</title>
    <link>https://forums.autodesk.com/t5/revit-api-forum/create-dynamic-iexternalcommand-class-at-runtime/m-p/10917876#M21081</link>
    <description>&lt;P&gt;Thanks&amp;nbsp;&lt;a href="https://forums.autodesk.com/t5/user/viewprofilepage/user-id/824630"&gt;@jeremy_tammik&lt;/a&gt;&amp;nbsp;for your help!&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;We actually do not need to generate the code dynamically, we could use parameters to create the class with certain property values. We have been giving a try to CodeDom.&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;We first created a namespace. We try two things; bringing the methods from another class which implements IExternalCommand and Implementing&amp;nbsp;IExternalCommand in the new class itself.&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;LI-CODE lang="general"&gt;namespace NewCodeDomClassNamespace
{
    class NewCodeDomClass
    {
        CodeCompileUnit targetUnit;
        CodeTypeDeclaration targetClass;
        public NewCodeDomClass(string nameassembly)
        {
            targetUnit = new CodeCompileUnit();
            CodeNamespace samples = new CodeNamespace(nameassembly);
            samples.Imports.Add(new CodeNamespaceImport("Methods.ClassWithIExternalCommand"));
            targetClass = new CodeTypeDeclaration(nameassembly);
            targetClass.IsClass = true;
            targetClass.TypeAttributes = TypeAttributes.Public;
            targetClass.BaseTypes.Add(typeof(Autodesk.Revit.UI.IExternalCommand));
            samples.Types.Add(targetClass);
            targetUnit.Namespaces.Add(samples);            
        }
}
}&lt;/LI-CODE&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;Then, OnStartup:&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;LI-CODE lang="general"&gt;                NewCodeDomNamespace.NewCodeDomClass newclass = new NewCodeDomNamespace.NewCodeDomClass("NewClass");

                PushButtonData button0data = new PushButtonData("NewClass.NewClass",
                nombreboton, _path, "NewClass.NewClass");&lt;/LI-CODE&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;However, when running the button, Revit throws an error saying that the class cannot be found in the add-in assembly.&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;Thanks&lt;/P&gt;</description>
    <pubDate>Mon, 31 Jan 2022 09:41:15 GMT</pubDate>
    <dc:creator>NonicaTeam</dc:creator>
    <dc:date>2022-01-31T09:41:15Z</dc:date>
    <item>
      <title>Create Dynamic IExternalCommand class at runtime</title>
      <link>https://forums.autodesk.com/t5/revit-api-forum/create-dynamic-iexternalcommand-class-at-runtime/m-p/10912874#M21079</link>
      <description>&lt;P&gt;Good morning,&lt;/P&gt;&lt;P&gt;We have been trying to create a class dynamically with IExternalCommand implemented in order to give the new class different names at runtime but still execute our desired method. Our code is:&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;LI-CODE lang="general"&gt;var ab = AssemblyBuilder.DefineDynamicAssembly(new AssemblyName(nombreassembly), AssemblyBuilderAccess.Run);
            
            var mb = ab.DefineDynamicModule(nombreassembly);

            var tb = mb.DefineType(nombreassembly);
            tb.AddInterfaceImplementation(typeof(IExternalCommand));

            foreach (var imethod in typeof(IExternalCommand).GetMethods())
            {
                var valueString = ((DescriptionAttribute)imethod.GetCustomAttribute(typeof(DescriptionAttribute))).Description;

                var method =
                  tb.DefineMethod
                  (
                    "@@" + imethod.Name,
                    MethodAttributes.Private | MethodAttributes.Static,
                    imethod.ReturnType,
                    new[] { tb }
                  );

                var thisParameter = Expression.Parameter(typeof(IExternalCommand), "this");

                var bodyExpression =
                  Expression.Lambda
                  (
                    Expression.Constant
                    (
                      Convert.ChangeType(valueString, imethod.ReturnType)
                    ),
                    thisParameter
                  );

                bodyExpression.CompileToMethod(method);

                var stub =
                  tb.DefineMethod(imethod.Name, MethodAttributes.Public | MethodAttributes.Virtual, imethod.ReturnType, new Type[0]);

                var il = stub.GetILGenerator();
                il.Emit(OpCodes.Ldarg_0);
                il.EmitCall(OpCodes.Call, method, null);
                il.Emit(OpCodes.Ret);

                tb.DefineMethodOverride(stub, imethod);
            }

            var fooType = tb.CreateType();
            var ifoo = (IExternalCommand)Activator.CreateInstance(fooType);&lt;/LI-CODE&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;We managed to get the methods within the interface using ifoo at the end, but we have two issues:&lt;/P&gt;&lt;P&gt;- We don´t know how to edit the Execute method within the interface after implementation to add our code to that method.&amp;nbsp;&lt;/P&gt;&lt;P&gt;- We have a line throwing one issue when debugging. This line is: var valueString = ((DescriptionAttribute)imethod.GetCustomAttribute(typeof(DescriptionAttribute))).Description;&lt;/P&gt;&lt;P&gt;The error is:&amp;nbsp;System.NullReferenceException: 'Object reference not set to an instance of an object.' Not sure which type should be set up in this case.&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;We would really appreciate you help into this.&lt;/P&gt;&lt;P&gt;Thank you&lt;/P&gt;</description>
      <pubDate>Fri, 28 Jan 2022 09:45:29 GMT</pubDate>
      <guid>https://forums.autodesk.com/t5/revit-api-forum/create-dynamic-iexternalcommand-class-at-runtime/m-p/10912874#M21079</guid>
      <dc:creator>NonicaTeam</dc:creator>
      <dc:date>2022-01-28T09:45:29Z</dc:date>
    </item>
    <item>
      <title>Re: Create Dynamic IExternalCommand class at runtime</title>
      <link>https://forums.autodesk.com/t5/revit-api-forum/create-dynamic-iexternalcommand-class-at-runtime/m-p/10912905#M21080</link>
      <description>&lt;P&gt;To redefine the Execute method, i would assume that you would want to generate dynamic source code:&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;&lt;A href="https://docs.microsoft.com/en-us/dotnet/framework/reflection-and-codedom/dynamic-source-code-generation-and-compilation" target="_blank"&gt;https://docs.microsoft.com/en-us/dotnet/framework/reflection-and-codedom/dynamic-source-code-generation-and-compilation&lt;/A&gt;&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;Why are you interested in the Description attribute? There is no need for it, is there?&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&amp;nbsp;&lt;/P&gt;</description>
      <pubDate>Fri, 28 Jan 2022 10:01:37 GMT</pubDate>
      <guid>https://forums.autodesk.com/t5/revit-api-forum/create-dynamic-iexternalcommand-class-at-runtime/m-p/10912905#M21080</guid>
      <dc:creator>jeremy_tammik</dc:creator>
      <dc:date>2022-01-28T10:01:37Z</dc:date>
    </item>
    <item>
      <title>Re: Create Dynamic IExternalCommand class at runtime</title>
      <link>https://forums.autodesk.com/t5/revit-api-forum/create-dynamic-iexternalcommand-class-at-runtime/m-p/10917876#M21081</link>
      <description>&lt;P&gt;Thanks&amp;nbsp;&lt;a href="https://forums.autodesk.com/t5/user/viewprofilepage/user-id/824630"&gt;@jeremy_tammik&lt;/a&gt;&amp;nbsp;for your help!&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;We actually do not need to generate the code dynamically, we could use parameters to create the class with certain property values. We have been giving a try to CodeDom.&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;We first created a namespace. We try two things; bringing the methods from another class which implements IExternalCommand and Implementing&amp;nbsp;IExternalCommand in the new class itself.&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;LI-CODE lang="general"&gt;namespace NewCodeDomClassNamespace
{
    class NewCodeDomClass
    {
        CodeCompileUnit targetUnit;
        CodeTypeDeclaration targetClass;
        public NewCodeDomClass(string nameassembly)
        {
            targetUnit = new CodeCompileUnit();
            CodeNamespace samples = new CodeNamespace(nameassembly);
            samples.Imports.Add(new CodeNamespaceImport("Methods.ClassWithIExternalCommand"));
            targetClass = new CodeTypeDeclaration(nameassembly);
            targetClass.IsClass = true;
            targetClass.TypeAttributes = TypeAttributes.Public;
            targetClass.BaseTypes.Add(typeof(Autodesk.Revit.UI.IExternalCommand));
            samples.Types.Add(targetClass);
            targetUnit.Namespaces.Add(samples);            
        }
}
}&lt;/LI-CODE&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;Then, OnStartup:&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;LI-CODE lang="general"&gt;                NewCodeDomNamespace.NewCodeDomClass newclass = new NewCodeDomNamespace.NewCodeDomClass("NewClass");

                PushButtonData button0data = new PushButtonData("NewClass.NewClass",
                nombreboton, _path, "NewClass.NewClass");&lt;/LI-CODE&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;However, when running the button, Revit throws an error saying that the class cannot be found in the add-in assembly.&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;Thanks&lt;/P&gt;</description>
      <pubDate>Mon, 31 Jan 2022 09:41:15 GMT</pubDate>
      <guid>https://forums.autodesk.com/t5/revit-api-forum/create-dynamic-iexternalcommand-class-at-runtime/m-p/10917876#M21081</guid>
      <dc:creator>NonicaTeam</dc:creator>
      <dc:date>2022-01-31T09:41:15Z</dc:date>
    </item>
    <item>
      <title>Re: Create Dynamic IExternalCommand class at runtime</title>
      <link>https://forums.autodesk.com/t5/revit-api-forum/create-dynamic-iexternalcommand-class-at-runtime/m-p/10917926#M21082</link>
      <description>&lt;P&gt;In that case, one of the arguments specifying the full class name may be incorrect. Maybe part of the class namespace prefix is missing. You can use some IL inspection tool to analyse your .NET assembly DLL and see exactly what full class names it defines:&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;&lt;A href="https://duckduckgo.com/?q=il+decompiler" target="_blank"&gt;https://duckduckgo.com/?q=il+decompiler&lt;/A&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&amp;nbsp;&lt;/P&gt;</description>
      <pubDate>Mon, 31 Jan 2022 10:10:20 GMT</pubDate>
      <guid>https://forums.autodesk.com/t5/revit-api-forum/create-dynamic-iexternalcommand-class-at-runtime/m-p/10917926#M21082</guid>
      <dc:creator>jeremy_tammik</dc:creator>
      <dc:date>2022-01-31T10:10:20Z</dc:date>
    </item>
    <item>
      <title>Re: Create Dynamic IExternalCommand class at runtime</title>
      <link>https://forums.autodesk.com/t5/revit-api-forum/create-dynamic-iexternalcommand-class-at-runtime/m-p/10918456#M21083</link>
      <description>&lt;P&gt;Why do you want to generate &lt;EM&gt;&lt;STRONG&gt;IExternalCommand&lt;/STRONG&gt; &lt;/EM&gt;dynamically?&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;I tried the CodeDom and didn't have any success.&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;By looking at the Assembly was not possible to find the dynamic class.&lt;/P&gt;&lt;LI-CODE lang="csharp"&gt;foreach (var item in Assembly.GetExecutingAssembly().GetTypes())
{
   Console.WriteLine(item);
}&lt;/LI-CODE&gt;&lt;P&gt;&amp;nbsp;Probably Revit does something similar when the button is executed.&lt;/P&gt;</description>
      <pubDate>Mon, 31 Jan 2022 14:01:43 GMT</pubDate>
      <guid>https://forums.autodesk.com/t5/revit-api-forum/create-dynamic-iexternalcommand-class-at-runtime/m-p/10918456#M21083</guid>
      <dc:creator>ricaun</dc:creator>
      <dc:date>2022-01-31T14:01:43Z</dc:date>
    </item>
    <item>
      <title>Re: Create Dynamic IExternalCommand class at runtime</title>
      <link>https://forums.autodesk.com/t5/revit-api-forum/create-dynamic-iexternalcommand-class-at-runtime/m-p/10918741#M21084</link>
      <description>&lt;P&gt;Thank you very much&amp;nbsp;&lt;a href="https://forums.autodesk.com/t5/user/viewprofilepage/user-id/4176855"&gt;@ricaun&lt;/a&gt;&amp;nbsp;! We also have been struggling the whole day using dotPeek with no success. Appreciate your comment.&lt;/P&gt;&lt;P&gt;We want to create a namespace and class dynamically because Revit journal files are logged using those when commands are executed. Our commands can be changed by the user and therefore we would like the Revit journal record to change with them.&lt;BR /&gt;EDIT:&lt;BR /&gt;We could not create classes using other methods from System. Reflection, maybe Revit blocks this behaviour.&lt;/P&gt;</description>
      <pubDate>Mon, 31 Jan 2022 19:15:51 GMT</pubDate>
      <guid>https://forums.autodesk.com/t5/revit-api-forum/create-dynamic-iexternalcommand-class-at-runtime/m-p/10918741#M21084</guid>
      <dc:creator>NonicaTeam</dc:creator>
      <dc:date>2022-01-31T19:15:51Z</dc:date>
    </item>
    <item>
      <title>Re: Create Dynamic IExternalCommand class at runtime</title>
      <link>https://forums.autodesk.com/t5/revit-api-forum/create-dynamic-iexternalcommand-class-at-runtime/m-p/10919361#M21085</link>
      <description>&lt;P&gt;Hello &lt;a href="https://forums.autodesk.com/t5/user/viewprofilepage/user-id/10727074"&gt;@NonicaTeam&lt;/a&gt; I was able to create some assembly on the fly!&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;&lt;span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="ricaun_0-1643659226763.gif" style="width: 400px;"&gt;&lt;img src="https://forums.autodesk.com/t5/image/serverpage/image-id/1018936i4A388DD848C93489/image-size/medium?v=v2&amp;amp;px=400" role="button" title="ricaun_0-1643659226763.gif" alt="ricaun_0-1643659226763.gif" /&gt;&lt;/span&gt;&lt;/P&gt;&lt;P&gt;&lt;div class="video-embed-center video-embed"&gt;&lt;iframe class="embedly-embed" src="https://cdn.embedly.com/widgets/media.html?src=https%3A%2F%2Fwww.youtube.com%2Fembed%2F6WAXUVYE4jY%3Ffeature%3Doembed&amp;amp;display_name=YouTube&amp;amp;url=https%3A%2F%2Fwww.youtube.com%2Fwatch%3Fv%3D6WAXUVYE4jY&amp;amp;image=https%3A%2F%2Fi.ytimg.com%2Fvi%2F6WAXUVYE4jY%2Fhqdefault.jpg&amp;amp;type=text%2Fhtml&amp;amp;schema=youtube" width="200" height="112" scrolling="no" title="Create IExternalCommand on the fly!" frameborder="0" allow="autoplay; fullscreen; encrypted-media; picture-in-picture;" allowfullscreen="true"&gt;&lt;/iframe&gt;&lt;/div&gt;&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;Here is the source code: &lt;A href="https://github.com/ricaun/RevitAddin.CodeCompileTest" target="_blank"&gt;https://github.com/ricaun/RevitAddin.CodeCompileTest&lt;/A&gt;&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;Have fun!&lt;/P&gt;</description>
      <pubDate>Mon, 31 Jan 2022 20:01:07 GMT</pubDate>
      <guid>https://forums.autodesk.com/t5/revit-api-forum/create-dynamic-iexternalcommand-class-at-runtime/m-p/10919361#M21085</guid>
      <dc:creator>ricaun</dc:creator>
      <dc:date>2022-01-31T20:01:07Z</dc:date>
    </item>
    <item>
      <title>Re: Create Dynamic IExternalCommand class at runtime</title>
      <link>https://forums.autodesk.com/t5/revit-api-forum/create-dynamic-iexternalcommand-class-at-runtime/m-p/10922774#M21086</link>
      <description>&lt;P&gt;Thank you&amp;nbsp;&lt;a href="https://forums.autodesk.com/t5/user/viewprofilepage/user-id/4176855"&gt;@ricaun&lt;/a&gt;&amp;nbsp;!! That was really helpful, we really appreciate that you took the time to help us.&amp;nbsp;&lt;/P&gt;</description>
      <pubDate>Wed, 02 Feb 2022 08:03:01 GMT</pubDate>
      <guid>https://forums.autodesk.com/t5/revit-api-forum/create-dynamic-iexternalcommand-class-at-runtime/m-p/10922774#M21086</guid>
      <dc:creator>NonicaTeam</dc:creator>
      <dc:date>2022-02-02T08:03:01Z</dc:date>
    </item>
  </channel>
</rss>

