Reputation: 91
sorry if the title is not clear, I'm not sure how to name what I'm looking for
I'm creating an addin for Revit that creates the buttons on the Revit interface, when the button is clicked, the addin invokes a dll from memory.
To implement IExternalApplication to create the button I need to create a class Invoke01 (hardcoded?) and refer to it in a string (is this Reflection?)
// 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
}
}
}
Then the hardcoded class loads another dll to memory
// 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;
}
}
}
}
I have to write this for the six addins I have now, and so a lot of code is repeated.
My first question is ¿How are these "hardcoded" classes actually called?
Ideally I would like to wrap all of the code from Invoke 01 in a ¿base class? (Again, I'm not sure what do I need to look for) so I don't have to repeat all of the code each time I create a new button, instead
I want to just define INVOKE_PATH, CMD_NAME and CMD_NUM, and then call that base class that does the rest.
I suppose using class inheritance, abstract classes or interfaces would be the way to go. For the first one I'm not sure how to implement it, for the last two, they just provide "blueprints" for the classes as far as I know.
Thanks,
Upvotes: 0
Views: 187
Reputation: 1220
I want to just define INVOKE_PATH, CMD_NAME and CMD_NUM, and then call that base class that does the rest.
Not sure if I understood you correctly, but I believe a function is literally what you're asking for. Base class will be overkill.
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;
}
}
}
}
Call it from anywhere in your app, for example:
public Result Execute(ExternalCommandData commandData, ref string message, ElementSet elements)
{
return DllUtilities.LoadAndInvoke(INVOKE_PATH, CMD_NAME);
}
It's probably sub-optimal — you should consider caching reference to loaded dll, perhaps even storing invocation action somewhere — but that's material for another question.
Upvotes: 2