It maybe would have been nice if AutoDesk added property to CommandAttribute that told it to add and start a transaction before calling you method and commiting it when control was returned and maybe exposed CancelCommit or you would have access to it with TopTransaction property.
The problem there is that I have very few commands implemented in .NET
that unconditionally start and commit a transaction. Most of those that do,
only do after all user interaction is done, and the user hasn't decided to
bail out. Ditto for document locking.
I think one would be hard-pressed to find very many cases where either or
both a transaction and a document lock wrap the
entire implementation
of a .command method.
One problem with the OP's wrapper for try/catch is that it doesn't rethrow the
exception, which means that it could only be useful when it wraps the
entirecommand implementation. If it were used in any other context, and there was
more code following the call to execute the action, that code would run as if no
error had occurred.
The .NET Application object has an event that fires when an exception is raised
and is not handled, which is how most do exception logging, but that event does
not get fired in AutoCAD and I think that's a notable deficiency, because if there
was an event that could be used to intercept unhandled exceptions, it would be
a far better way to solve the problem which the OP's wrapper tries to solve.
Maybe for 5.0 if possible with Roslyn project to call dispose on all newly created Dbobjects that are not added to the Database when they fall out of scope.
It's not when a DBObject wrapper goes out of scope, it's when it becomes
unreachable through code (and becomes eligible for garbage collection) that
would be the trigger. If there's only one variable on the stack referencing a
DBObject, then it is simple, but the problem is there's no easy way to find out
when an object has become unreachable, and compiler extensions you speak
of (Rosyln) that allow you to hook into the compilation process won't really
help with that problem. The garbage collector itself doesn't even know when
an object becomes unreachable, it must scan the heap and stack each time it
does a sweep to find out.