创建 类 不重复调用的代码

Create classes that does not repeat code to invoke

抱歉,如果标题不清楚,我不确定如何命名我要查找的内容

我正在为 Revit 创建一个插件,它在 Revit 界面上创建按钮,单击按钮时,插件会从内存中调用一个 dll。

要实现 IExternalApplication 以创建按钮,我需要创建一个 class Invoke01(硬编码?)并在字符串中引用它(这是反射吗?)

// ButtonsApp.dll
// +-- ThisApplication.cs

namespace ButtonsApp
{
    [Autodesk.Revit.Attributes.Transaction(Autodesk.Revit.Attributes.TransactionMode.Manual)]
    [Autodesk.Revit.DB.Macros.AddInId(GlobalVars.addinId)]
    public class ThisApplication : IExternalApplication
    {
        public Result OnStartup(UIControlledApplication uiApp)
        {

// ...etc

 PushButtonData pushButtonOne = new PushButtonData(buttonOneName, 
                                                     buttonOneName,
                                                     exeConfigPath,
                                                     "ButtonsApp.Invoke01"); // Invoke class

// ...etc
        }
    }
}

然后硬编码class加载另一个dll到内存

// ButtonsApp.dll
// +-- Invokers.cs

namespace ButtonsApp
{
    [Autodesk.Revit.Attributes.Transaction(Autodesk.Revit.Attributes.TransactionMode.Manual)]
    public class Invoke01 : IExternalCommand
    {
        public Result Execute(ExternalCommandData commandData, ref string message, ElementSet elements)
        {
            try
            {

                string assemblyPath = INVOKE_PATH;

                // Code that loads dll to memory to execute the command

                string strCommandName = CMD_NAME;

                // Some more code

                return Result.Succeeded;
            }
            catch (Exception ex)
            {
                Utils.CatchDialog(ex, CMD_NUM);
                return Result.Failed;
            }
        }
    }
}

我必须为我现在有的六个插件写这个,所以重复了很多代码。

我的第一个问题是¿这些“硬编码”class实际上是如何调用的?

理想情况下我想将 Invoke 01 中的所有代码包装在一个 ¿base class 中? (同样,我不确定我需要寻找什么)所以我不必在每次创建新按钮时都重复所有代码,而是

我只想定义 INVOKE_PATH、CMD_NAME 和 CMD_NUM,然后调用该基数 class 完成其余部分。

我想使用 class 继承、抽象 classes 或接口将是可行的方法。 对于第一个,我不确定如何实现它,对于最后两个,据我所知,他们只是为 classes 提供了“蓝图”。

谢谢,

I want to just define INVOKE_PATH, CMD_NAME and CMD_NUM, and then call that base class that does the rest.

不确定我是否理解正确,但我相信函数正是您所要求的。 Base class 会有点矫枉过正。

namespace ButtonsApp
{
    class DllUtilities
    {
        public static Result LoadAndInvoke(string assemblyPath, string commandName)
        {
            try
            {
                // >> here goes dll loading and invocation <<
                // ...
                return Result.Succeeded;
            }
            catch (Exception ex)
            {
                Utils.CatchDialog(ex, CMD_NUM);
                return Result.Failed;
            }
        }
    }
}

从您应用中的任何位置调用它,例如:

        public Result Execute(ExternalCommandData commandData, ref string message, ElementSet elements)
        {
            return DllUtilities.LoadAndInvoke(INVOKE_PATH, CMD_NAME);
        }

它可能不是最优的 — 您应该考虑缓存对加载的 dll 的引用,甚至可能在某处存储调用操作 — 但那是另一个问题的 material。