How to use the Enterprise Architect Add-in Framework
Since I started writing the EA Navigator and other tools the code has been open source and available on Github. The code is split up in a tool-specific part for the EA Navigator and some other tools, and a framework that can be used to build your own tool.
Downloading
The code for the framework and the tools is published on GitHub, a version control repository “in the cloud”, which is free for public repositories. The easiest way to download the code is to install GitHub for Windows. That allows you use the Clone in Desktop button on Github.
You can also download the ZIP, but then you’ll have to rename the packages to their original name. To be able to use the framework you’ll need two repositories
If you want to see how the EA Navigator uses the framework you’ll need
Make sure you put all the projects in the same directory as otherwise the references would be broken.
Compiling
The code for the EA Add-in framework is written in C# using SharpDevelop. You can also open it with Visual Studio or another C# IDE, but then you’ll have to remove the wix projects from the solution.
You can open the complete code in either the Enterprise-Architect-Toolpack \Total Solution.sln or in case you only downloaded the framework then Enterprise-Architect-Add-in-Framework\Total Solution.sln but make sure to start you IDE as administrator.
Before compiling check the reference to Interop.EA. I’ve set it to point to C:\Program Files (x86)\Sparx Systems\EA\Interop.EA.dll but if you have EA installed in another directory you’ll need to replace the existing reference.
Once the references are OK you should be able to compile the solution without any issues.
The pattern
To be able to understand the architecture of the framework you’ll have to understand the pattern behind it.
On the right you see a diagram of the general modelling tooling pattern. This pattern describes how to create tools that extend the features of a standard modelling tool in order to support the modelling method used.
This is the pattern I use whenever I develop an Enterprise Architect add-in for a client.
The LanguageObject is an interface that represent the object of the modelling language. In the case of UML each meta class of the meta model is represented as an interface. The LanguageObjects are completely independent of the modelling method or modelling tool used. Once finished this layer hardly ever changes.
The LanguageObject is then implemented by the ToolWrapper. There will be a ToolWrapper layer for each supported case tool. The ToolWrapper wraps the ToolObjects of the case tools API using the adapter pattern.
The MetaObject is only required when you are implementing a tool for a specific modelling method. These MetaObjects represent the meta classes of the modelling methods meta model. They wrap the LanguageObject using the adapter pattern. General tools that are not specific to any modeling method, such as the EA Navigator can skip this layer and use the LanguageObjects directly.
The Client is the actual tool. It only uses the MetaObjects to actually do its job.
In order for this pattern to actually work, it is really important that the dependencies and layers are respected.
The architecture
To make an add-in you’ll always need three components similar to the three repositories on GitHub. You can see how these component map onto the pattern on the diagram.
UML Tooling Framework
The UML Tooling framework implements the LanguageObjects of the pattern for the UML language. Each element of the UML meta model is represented as a interface defining all attributes and operations as defined in the UML Superstructure.
Enterprise Architect Addin Framework
This component implements the ToolWrappers of the pattern. This component actually knows about the Enterprise Architect API. It hides all the ugliness of the API behind a clean set of UML interface implementations. There is a also a bunch of helper functions and stuff like that to make things a bit easier to work with.
The Enterprise Architect Add-in Framework also contains an abstract add-in class EAAddinBase that you can inherit from to quickly create a new add-in.
The add-in component
The add-in component is the part that is specific to the add-in. It contains the actual logic and behavior that needs to be executed. This is also that part that you tell Enterprise Architect about. EA will then call the prescribed methods such as EA_GetMenuItem or EA_MenuClick on the AddinClass at the appropriate moments.
When done correctly only the EA_ operations use API objects in their parameters. The first thing they should do is create the appropriate wrapper class and execute the required behavior on that wrapper. We cannot avoid the dependency to EA’s API because of the parameters in the EA_ methods, but it should be restricted to the parameters only. Make sure the only class that depends on Interop.EA.dll is the AddinClass, and leave this class as bear bones as possible. All functionality should go into functional classes who don’t depend on Interop.EA.dll.
You could even consider to split the MyAddin.dll into two parts, one for only the AddinClass, and one for the functional classes. This would definitely be the preferred architecture once you have multiple add-ins that somehow can re-use some of the functional classes.
More resources
Related articles
- Tutorial: Create your first C# Enterprise Architect addin in 10 minutes
- Tutorial: Deploy your Enterprise Architect C# add-in with an MSI package
- Testing and debugging your Enterprise Architect C# Add-in
- The complete Enterprise Architect C# add-in template
Geert, this all looks great and very professional to me, thanks a lot for sharing!
I have managed to clone the repositories so far. And I have found out, that WiX is compatible with VS 2013 (of which I use the community edition). So far so good.
But VS on building the solution, the UMLToolingFramework compiles OK, but the EAAddinFramwork doesn’t compile, VS reports “Could not locate the assembly “LogicNP.CryptoLicensing” . This seems to be a 3rd party library and I don’t really know how to proceed. Any hints you (or anyone else) could give?
Thanks
Hermann
Hi Herman,
The LogicNP.CryptoLicensing is indeed a third party library used only by the license class (which is used by EA-Matic)
If you don’t want to use this then you should be able to remove the reference and comment out the sections in the code that use this library.
I should figure out a way to make that easier I guess. If you have any ideas let me know.
Geert
Thanks, Geert, that worked (I simply uncommented some stuff. If I come across a generic solution, I’ll let you know.)
Hermann
Hi Geert,
Let me first thank you for putting this framework toegether. It is really great!!
I managed to add elements using the addToDiagram. However, I tried a lot of stuff but were not able to remove elements from a diagram (while keeping it in the model). Could you please give me a hint?
Thanks in advance
Jan
Removing elements from a diagram is simply deleting the diagramObjects from the EA.Diagram.DiagramObjects collection using the method EA.Diagram.DiagramObjects.DeleteAt()
I don’t think I ever needed that, so I don’t have a method “removeFromDiagram” yet, but it’s basically the same as removing a tagged value or an operation from an element.
Hi Geert,
Thank you for this great framework you have created. It has been helping me a lot with practicing C# which I have recently started learning.
I have a question, hoping you can guide me. I’m trying to make an addition to your example add-in “MyAddinClass”. I want to have a menu item (let’s call it “GenerateCode”) that initializes the auto code generation.
I believe this menu item needs to get the GUID of the selected package using the interface “IDualPAckage”; then use the method “GetPackageByGuid” to access the package; later use “GetProjectInterface()” to access the utility function “GeneratePackage”, and generate the code from the package.
Is this a correct approach for initializing auto code generation? Is there need to be something else, such as an s click event involved?
Seems about right. If you get stuck somewhere you can post a question on either the Sparx Forum Stackoverflow
I usually monitor both.
Geert
Thank you for the help Geert. 🙂