First, use case-insensitive string comparison on file names.
Second, you don't need to worry about whether a Database is
open in the editor, or not. If the database is open in the editor,
it's AutoDelete property will be false, otherwise it will be true.
You only need to call Dispose() on a database if it is not open
in the editor:
Database db = // call your function to assign db
try
{
// use db here
}
finally
{
if( db.AutoDelete )
db.Dispose();
}
You can also use 'Using' and call Dispose() on the
Database in any case, because a Database knows
what to do when you call its Dispose(), depending
on whether it's open in the editor, or not.
I've said in the past that one should not call Dispose()
on a Database that's open in the editor, but my own
opinion on that now is that it's ok in cases where you
may be dealing both types (databases that are open
in the editor, and ones created by calling the new()
constructor and ReadDwgFile()).
If for another reason you need to know if a Database
is open in the editor, you can tell by just looking at
its AutoDelete property.
As far as disposing objects you get from a database, you
don't have to do that unless disposing an object has a
side-effects (which is the case with Transactions). For
other objects, you don't need to call Dispose().
You can also not bother calling Dispose() on any DBObject
that you get from a Transaction, because the transaction
manages the object for you.
Other things I noticed you calling Dispose() on (like the
TransactionManager for example), you should not call
Dispose() on, because in many cases, those objects are
managed by an 'owner' object (the object that you get
them from via referencing a property or calling a method
of the 'owner' object).
While in most cases needless calls to Dispose() will do
no harm, that is not the case for the Document object,
and is why you have to be careful about what you call
Dispose() on.
My personal opinion about the seemingly massive and
widepsread confusion that exists on the matter of what
should be disposed and what shouldn't be disposed, is
that it is largely a product of extremely poor API design
on Autodesk's part.
I have a lisp application that I want to re-write in vb.net as an learning excersize. Some of the approaches I use in lisp work well, but I'm thinking they may not work well in dot net.
For example, I have a function that takes a fully qualified pathname to a drawing file and returns a document object. This is done by first checking the active document, then the documents collection, and if it still hasn't found the target drawing it then tries to open the drawing using objectdbx. The one thing I have to be careful with is that the calling routine has to be sure to release the document object when it's done with it.
I use this procedure in a variety of programs where I need a document object.
Below is the vb.net code I have developed for this:
Suggestions are welcome.
Private Function GetRemoteDb(ByVal DocPathName As String) As Autodesk.AutoCAD.DatabaseServices.Database
Dim colDocs As Autodesk.AutoCAD.ApplicationServices.DocumentCollection
Dim ActiveDoc As Autodesk.AutoCAD.ApplicationServices.Document
ActiveDoc = ApplicationServices.Application.DocumentManager.MdiActiveDocument
'if our document is the active document, then return it.
If ActiveDoc.Name = DocPathName Then
Return ActiveDoc.Database
Exit Function
End If
'if our document is already open then return it
colDocs = ApplicationServices.Application.DocumentManager
For Each doc As ApplicationServices.Document In colDocs
If doc.Name = DocPathName Then
Return doc.Database
Exit Function
End If
Next
'if the document doesn't exist, then throw an error
If Not My.Computer.FileSystem.FileExists(DocPathName) Then
Throw New System.IO.FileNotFoundException
End If
'it exists, and isn't open, so let's open and return it
Dim dbTarget As New Database(False, True)
Try
dbTarget.ReadDwgFile(DocPathName, FileOpenMode.OpenForReadAndAllShare, False, "")
If dbTarget.Filename = DocPathName Then
Return dbTarget
Exit Function
End If
Catch ex As Exception
Debug.Print("Oops, we seem to have had an error " & ex.Message)
End Try
GetRemoteDb = dbTarget
End Function
Now the question. Should I be building a RemoteDoc class to ensure handle the disposing of the objects that this procedure generates? Is there a better way (probably many) to skin this cat?