The AutoCAD .NET API DBObject.CreateExtensionDictionary() looks easy to use, however that good look may indicate that something is hidden from users. For example, if the extension dictionary always exists in the DBObject, what the CreateExtensionDictionary() call will give us?
We can figure it out easily with a good AutoCAD .NET programming experiment. Here it is.
[CommandMethod("CreateExtensionDictionaryWithoutChecking", CommandFlags.Modal)]
public void CreateExtensionDictionaryWithoutChecking_Method()
{
Editor ed = MgdAcApplication.DocumentManager.MdiActiveDocument.Editor;
try
{
PromptEntityOptions prEntOpt = new PromptEntityOptions("\nSelect an entity having Extension Dictionary");
PromptEntityResult selRes = ed.GetEntity(prEntOpt);
if (selRes.Status == PromptStatus.OK)
{
using (Transaction tr = MgdAcApplication.DocumentManager.MdiActiveDocument.TransactionManager.StartTransaction())
{
Entity ent = (Entity)tr.GetObject(selRes.ObjectId, OpenMode.ForWrite);
ent.CreateExtensionDictionary();
tr.Commit();
}
}
else
ed.WriteMessage("\nCircle selection failed!");
}
catch (System.Exception ex)
{
ed.WriteMessage(Environment.NewLine + ex.Message);
}
}
After the command runs, if an entity having Extension Dictionary is selected, the following output will be there in the command line window.
Command: CreateExtensionDictionaryWithoutChecking
Select an entity having Extension Dictionary:
eAlreadyInDb
As shown, an exception with the error status eAlreadyInDb is thrown out in such a situation. It is not convenient, as the exception throw-out will interrupt the regular workflow. Wonder why the CreateExtensionDictionary() method returns void instead of a boolean indicating the extension dictionary creation succeeds or fails. Or, the CreateExtensionDictionary() method can return an ObjectId pointing to either the new or old extension dictionary and we can use the id to open the dictionary right away rather than call another property, ExtensionDictionary, of the same DBObject so as to get the ObjectId.
Anyhow, we canon do anything about it, it seems a good practice to always check the existence of Extension Dictionary of the object of concern before the DBObject.CreateExtensionDictionary() method is called upon it. Here is a good example.
public static ObjectId GetSetExtensionDictionaryEntry(ObjectId id, string entryName)
{
ObjectId ret = ObjectId.Null;
using (Transaction tr = HostApplicationServices.WorkingDatabase.TransactionManager.StartTransaction())
{
DBObject obj = (DBObject)tr.GetObject(id, OpenMode.ForRead);
if (obj.ExtensionDictionary == ObjectId.Null)
{
obj.UpgradeOpen();
obj.CreateExtensionDictionary();
obj.DowngradeOpen();
}
DBDictionary dict = (DBDictionary)tr.GetObject(obj.ExtensionDictionary, OpenMode.ForRead);
if (!dict.Contains(entryName))
{
Xrecord xRecord = new Xrecord();
dict.UpgradeOpen();
dict.SetAt(entryName, xRecord);
tr.AddNewlyCreatedDBObject(xRecord, true);
ret = xRecord.ObjectId;
}
else
ret = dict.GetAt(entryName);
tr.Commit();
}
return ret;
}
On the other hand, here is a bad usage for the DBObject.CreateExtensionDictionary().
Dim tr As Transaction = trMgr.StartTransaction
Try
Dim obj As AcObject = tr.GetObject(resEnt.ObjectId, AcDb2.OpenMode.ForWrite)
obj.CreateExtensionDictionary()
...
The leading edge AutoCAD .NET Addin Wizard (AcadNetAddinWizard) provides various project wizards, item wizards, coders and widgets to help program AutoCAD .NET addins.
Posted by: |