Last year I shared how to figure out if Revit is in the API Context using events to trigger some exception, Revit only allow to add a new event in Idling or other Revit API event when Revit is in context.
Now I find out a easier and faster way using the ActiveAddInId, and better explain what the Revit API context means.
Like the add events in Revit API the ActiveAddInId is only available when Revit is in context, if is not in context the ActiveAddInId returns null.
Meaning Revit tracks the Revit AddIn Context with the propriety ActiveAddInId.
And every time your code add/remove a Revit API event, create a push button, create an ExternalEvent, or interact with Revit API in some way, Revit verify what AddIn is executing that code to update the ActiveAddInId when the event is trigger, or the push button, or ExternalEvent, and so on.
For me ActiveAddInId explain very well how Revit works, you need to have a valid AddInId to execute Revit API code, and yes, is the same AddIn the user need to allow when an AddIn is installed and Revit first open showing Security popup.
AddIn Context
The video below shows some explanation how ActiveAddInId is used inside Revit API to track what AddIn is executing in the moment a Revit API method is executed, an invalid ActiveAddInId could generate an exception and some methods really require the same AddInId to work without issue.
To check if Revit is in AddIn Context the code below could be used.
Design Automation for Revit
The main reason I decide to look closer in the propriety ActiveAddInId was an issue inside Design Automation:
The issue is related with Extensible Storage, and the Schema have this two method ReadAccessGranted and WriteAccessGranted, and if the AccessLevel was configured to Vendor or Application, Design Automation fails.
Design Automation for Revit uses a custom library to execute the event DesignAutomationReadyEvent, that event is executed when Design Automation is ready to execute. Because is not an official event inside Revit API the event never tracks the ActiveAddInId and when the event is executed the ActiveAddInId is invalid and return null.
I created a RevitTest project to NUnit test the Extensible Storage with different AccessLevel.
How to Fix ActiveAddInId in DA4R
To fix ActiveAddInId in DA4R the best approach I found was to register a custom ExternalService in the OnStartup and in the DesignAutomationReadyEvent event I can request and execute the ExternalService.
ExternalService exists in the main Revit API and tracks the ActiveAddInId, and every time the ExternalService executes the same ActiveAddInId owner is apply in the service.
The ExternalService is a little advanced topic, here some resources:
- https://thebuildingcoder.typepad.com/blog/2015/12/external-services.html#6
- https://thebuildingcoder.typepad.com/files/sd10752_revit_external_services_arnost_lobel_handout.pdf
ricaun.Revit.DA
I’m planing to create a library to fix two problems inside DA4R.
The library would simplify and force the DesignAutomationReadyEvent to execute a custom ExternalService to force the code to run with a valid ActiveAddInId.
And force to reload the correct ‘.addin’ inside the ‘PackageContents.xml’ in the bundle configuration, at the moment DA4R load the first AddIn in the configuration and ignore the version.
Stay tuned for a video in youtube about that library.