【问题标题】:Create classes that does not repeat code to invoke创建不重复调用代码的类
【发布时间】:2020-06-21 11:12:03
【问题描述】:

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

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

要实现 IExternalApplication 来创建按钮,我需要创建一个类 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
        }
    }
}

然后硬编码的类将另一个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;
            }
        }
    }
}

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

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

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

我只想定义 INVOKE_PATH、CMD_NAME 和 CMD_NUM,然后调用那个基类来完成其余的工作。

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

谢谢,

【问题讨论】:

    标签: c# class revit-api


    【解决方案1】:

    我只想定义 INVOKE_PATH、CMD_NAME 和 CMD_NUM,然后调用那个基类来完成剩下的工作。

    不确定我是否正确理解了您,但我相信函数实际上就是您所要求的。基类将是矫枉过正。

    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 的引用,甚至可能将调用操作存储在某处——但​​这是另一个问题的材料。

    【讨论】:

    • 既然你提到它,这实际上是显而易见的。我真的全神贯注地搜索和研究抽象和继承是如何工作的,以至于我忘记了一个函数可以做到这一点。谢谢。对于答案的最后一部分,您的意思是使用 MemoryCache 类吗?
    • @G-BC 我的意思是拥有将 dll 路径映射到加载的 dll 实例的字典(无论您使用哪种格式)。每当再次请求 dll 时,它可能会立即直接从字典中获取,而不是再次加载。
    猜你喜欢
    • 2013-03-22
    • 2017-05-26
    • 2018-12-12
    • 1970-01-01
    • 2021-11-02
    • 2011-10-12
    • 1970-01-01
    • 2017-02-14
    • 2013-09-06
    相关资源
    最近更新 更多