In part three of our series on LINQ and AutoCAD we created a neat way to access all tables of the drawing database. In this post we'll have a look at how to add AutoCAD dictionaries to our GeneralHelper class.
Dictionaries
Which dictionaries of interest do we have in the drawing database? Figuring this out is almost the same like for tables: the database object has some properties that end with DictionaryId. And again, like for tables, there is one element type for each dictionary. Let's bring it all together in tabular form:
ID property
Dictionary entry type
ColorDictionaryId
DBObject
DataLinkDictionaryId
DataLink
DetailViewStyleDictionaryId
DetailViewStyle
GroupDictionaryId
Group
LayoutDictionaryId
Layout
MaterialDictionaryId
Material
MLeaderStyleDictionaryId
MLeaderStyle
MLStyleDictionaryId
MlineStyle
NamedObjectsDictionaryId
DBObject
PlotSettingsDictionaryId
PlotSettings
PlotStyleNameDictionaryId
PlaceHolder
SectionViewStyleDictionaryId
SectionViewStyle
TableStyleDictionaryId
TableStyle
VisualStyleDictionaryId
DBVisualStyle
A few comments:
I couldn't figure out the data type of entries of the color dictionary. Let's stick with DbObject for the moment.
The named objects dictionary is kind of a "meta" container. It holds all dictionaries of this list and some other objects. So from a Add-In developer's perspective, this dictionary is not really of interest, so it's safe to leave it out.
The plot style names dictionary simply contains the plot style names, so there's no need to use GetDictItems, but rather we return the dictionary keys, which are the plot style names (we'll see that in listing 3).
Implementation
Alright, on to the implementation! First let's recap how we get records from AutoCAD tables:
That was easy. Getting dictionary entries is quite similar:
At first we get the IEnumerable to iterate the IDs. But here's the difference between dictionaries and tables: each entry of the dictionary's iterator is a DBDictionaryEntry, which holds the object's name as the key, and the ObjectId as the value. So we have to cast the value to ObjectId. And to be on the safe side we first check wheather the dictionary ID is valid at all (line 4).
Now we can add the GetDictItems() method to our GeneralHelper class. To not confuse the two getter methods, we rename GetItems() - which returns records from a table - to GetTableItems(). Finally, for each dictionary in our list above (except the named objects dictionary), we add a property that calls GetDictItems() to the GeneralHelper.
And so our GeneralHelper finally looks like this:
The power of abstraction
The great thing about the GeneralHelper class is that it abstracts away all details about how and where items are stored in the drawing database. The class provides one uniform way to access tables and dictionaries, no knowledge about details necessary. From the client's perspective, each "container" is of the most general container type available in .NET: IEnumerable<T>. And this gives us all the benefits of LINQ out of the box.
In the next post we'll have a look at some special object of the AutoCAD API, like the model space and paper space. We integrate these objects into the GeneralHelper, to make them easily querable using LINQ.