Создавайте классы, которые не повторяют код для вызова - PullRequest
0 голосов
/ 21 июня 2020

извините, если заголовок неясен, я не уверен, как назвать то, что я ищу

Я создаю надстройку для 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, а затем вызовите этот базовый класс, который сделает все остальное.

Я полагаю, использование наследования классов, абстрактных классов или интерфейсов было бы способом go. Для первого я не уверен, как это реализовать, для последних двух они просто предоставляют "чертежи" для классов, насколько мне известно.

Спасибо,

1 Ответ

2 голосов
/ 21 июня 2020

Я хочу просто определить 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, возможно, даже где-то хранится действие вызова - но это материал для другого вопроса.

...