/// <summary> /// Shut down this instance. Disposes all connections it holds and restores the prior scope. /// </summary> public void Dispose() { if (!IsDisposed) { // Firstly, remove ourselves from the stack (but, only if we are the one on the stack) // Note: Thread-local _currentScope, and requirement that scopes not be disposed on other threads // means we can get away with not locking. if (__currentScope == this) { // In case the user called dispose out of order, skip up the chain until we find // an undisposed scope. DbConnectionScope prior = _priorScope; while (null != prior && prior.IsDisposed) { prior = prior._priorScope; } __currentScope = prior; } // secondly, make sure our internal state is set to "Disposed" IDictionary <object, DbConnection> connections = _connections; _connections = null; // Lastly, clean up the connections we own foreach (DbConnection connection in connections.Values) { connection.Dispose(); } } }
/// <summary> /// Constructor /// </summary> public DbConnectionScope() { // Devnote: Order of initial assignment is important in cases of failure! // _priorScope first makes sure we know who we need to restore // _connections second, to make sure we no-op dispose until we're as close to // correct setup as possible // __currentScope last, to make sure the thread static only holds validly set up objects _priorScope = __currentScope; _connections = new Dictionary <object, DbConnection>(); __currentScope = this; }