To revisit this.
Seems like this might be useful for forcing requirements you want to implement.
You do take some performance hits but,
do you guys think it would be useful or good practice to use contracts only for debug build and removed for release build?
I was not thinking to use them for any logic responsible for checking user input or null checks etc...., but maybe something like routines you want to require a transaction to be active.
On the other hand just checking if the TopTransaction is null probably does not use many cycles.
Just threw it in somewhere and come to think of it, since it is a extension method for type derived from DBObject I would hope there was a transaction open anyway.
public static IEnumerable<T> GetEntries<T>(this DBDictionary dic, OpenMode mode = OpenMode.ForRead, bool openErased = false) where T : DBObject
{
if (dic == null)
{
throw new ArgumentNullException
("source"); }
Contract.Requires(dic.IsTransactionResident);
//////OR
Contract.Requires(dic.Database.TransactionManager.TopTransaction != null);
//////OR
Contract.Requires(dic.Database.TransactionManager.NumberOfActiveTransactions > 0);
TransactionManager tm = dic.Database.TransactionManager;
foreach (var entry in openErased ? dic.IncludingErased : dic)
{
yield return (T)tm.GetObject(entry.Value, mode, openErased, false);
}
}
The code I used for runtime checks like that one has been around longer than code contracts and most was written while .NET 2.0 was current, so I've not migrated to them, but they're similar to the framework classes.
I routinely use a very simple class called 'Assert' with members like IsNotNull(), IsNotNullOrEmpty(), IsTrue(), IsFalse(), etc... I could have them delegate to the framework equivalent APIs too, but haven't bothered since they working just fine.
In my Linq libraries, the check for an active transaction is done implicitly by a call to a method called GetTransaction(), which is overloaded to take a DBObject, ObjectId, IEnumerable, etc... They return the top transaction or throw an exception if no transactions are active.
The major problem I've been trying to figure out how to solve without major surgery, is how to support both OpenCloseTransactions and regular old Transactions at the same time. It's not trivial because OpenCloseTransactions aren't really transactions, so for example, in the code you show above, if the object whose IsTransactionResident property was opened with an OpenCloseTransaction, IsTransactionResident will be false.