Developing complex plugins for Revit is impossible without saving important for correct working information. There are multiple approaches depending on plugin type, requirements, information and so on to save and load this information. One of the most convenient is provided directly from Revit API – Extensible Storage.
The Revit API allows you to create your own class-like Schema data structures and attach instances of them to any Element in a Revit model. Schema-based data is saved with the Revit model and allows for higher-level, metadata-enhanced, object-oriented data structures.
As it mentioned in documentation, Schema is limited to fields it can contain. Fields can only be a simple type, an array, or a map. However, in some cases these limitations can be bypassed using JSON as a string data. This approach is used in Rebar Preset Manager, Rebar Bending Manager and Rebar Hook Manager to effectively store necessary information for these tools.
To perform working with Extensible Storage in Revit Smart Rebar System plugin special class was created – Storage Manager. Storage Manager can save and load entities with necessary data into Revit Elements. Generic methods can allow to save and load any types of information from Extensible Storage.
private static T GetData<T>(Element element, string fieldName)
{
var entity = element.GetEntity(StorageSchema);
return !entity.IsValid() ? default : entity.Get<T>(fieldName);
}
private static T GetJsonData<T>(Element element, string fieldName)
{
var jsonString = GetData<string>(element, fieldName);
return jsonString == null ? default : JsonConvert.DeserializeObject<T>(jsonString);
}
private static void SaveData<T>(Element element, string fieldName, T data)
{
var entity = element.GetEntity(StorageSchema);
if (!entity.IsValid())
{
entity = new Entity(StorageSchema);
}
if (data == null)
{
entity.Clear(fieldName);
}
else
{
entity.Set(fieldName, data);
}
element.SetEntity(entity);
}
There are also some disadvantages using JSON approach, such as, migration problem – when you have to change structure of you JSON data, but it can be solved using additional logic.
Since data are stored directly into Revit Elements, we don’t need to match data to element – they are already linked. This is very convenient when your information should be unique or have some differences from one element to another.
Apart from storing data in specific elements of project, Revit API also provides ability to store some data project-wide. This means, using DataStorage class we can store Add-In settings specified for this project. The approach to work with Data Storage is similar to Extensible Storage. Since DataStorage
class is inherited from Element
class, DataStorage
instance can be treated like Element
. Thus, we can use same logic to store and load data from it. It is good to have additional Schema
for DataStorage
instead overextending schema from Extensible Storage. DataStorage
instances can be loaded using FilteredElementCollector class. DataStorage
instances are stored like elements inside project, therefore during creating instance we should assign unique name to distinguish different instances from each other.