/// <summary>
        /// Creates and returns the primary connection object
        /// </summary>
        public virtual DbConnection GetConnection()
        {
            if (string.IsNullOrEmpty(ConnectionString))
            {
                try
                {
                    ConnectionString = System.Configuration.ConfigurationManager.AppSettings[DbConnectionStringName];
                }
                catch (Exception xc)
                {
                    throw new Exception(string.Format("unable to determine connection string. The AppSettings config key used was: {0}", DbConnectionStringName), xc);
                }
            }

            DbConnection con = TransactionBoundConnectionManager.GetAmbientConnection(CreateNewConnection);

            if (con == null)
            {
                con = CreateNewConnection();
            }

            if (con.State == ConnectionState.Closed)
            {
                con.Open();
            }
            return(con);
        }
        private void TransactionCompleted(object sender, System.Transactions.TransactionEventArgs e)
        {
            TransactionInformation ti = e.Transaction.TransactionInformation;

            if (ti.Status == TransactionStatus.Aborted || ti.Status == TransactionStatus.Committed)
            {
                string key = ti.LocalIdentifier;
                lock (_ActiveManagerLock)
                {
                    //Don't interfere too much - just let go. This will help maintain flexibility for developers
                    if (_ActiveManagers.ContainsKey(key))
                    {
                        TransactionBoundConnectionManager tim = _ActiveManagers[key];
                        if (tim._CurrentConnection != null)
                        {
                            tim._CurrentConnection.Close();
                        }
                        _ActiveManagers.Remove(key);
                    }

                    //if there are other managers around, start their auto kill
                    foreach (TransactionBoundConnectionManager tim in _ActiveManagers.Values)
                    {
                        tim.StartAutoKill();
                    }
                }
            }
        }
        internal static DbConnection GetAmbientConnection(GetConnection getConnectionMethod)
        {
            DbConnection dbCon;
            Transaction  tran = Transaction.Current;

            if (tran == null || tran.TransactionInformation.Status == TransactionStatus.Committed || tran.TransactionInformation.Status == TransactionStatus.Aborted)
            {
                dbCon = null;
            }
            else
            {
                if (getConnectionMethod == null)
                {
                    throw new ArgumentNullException("getConnectionMethod");
                }

                TransactionBoundConnectionManager tim = GetManager(tran);
                dbCon = tim._CurrentConnection;
                if (dbCon == null)
                {
                    dbCon = getConnectionMethod();
                    tim._CurrentConnection = dbCon;
                }
            }

            return(dbCon);
        }
        private void AutoRemove(object state)
        {
            try
            {
                TransactionInformation ti = _CurrentTransaction.TransactionInformation;

                string key = ti.LocalIdentifier;
                lock (_ActiveManagerLock)
                {
                    if (_ActiveManagers.ContainsKey(key))
                    {
                        try
                        {
                            TransactionBoundConnectionManager tim = _ActiveManagers[key];
                            if (tim._CurrentConnection != null)
                            {
                                tim._CurrentConnection.Close();
                            }
                            _ActiveManagers.Remove(key);
                        }
                        catch
                        {
                        }
                    }
                }
            }
            catch { }
        }
 /// <summary>
 /// Closes the connection. If the transaction object is not null, The connection will not be closed.
 /// You may change this method to handle the finalization in a different way
 /// </summary>
 public static void FinalizeConnection(DbConnection dbCon, DbTransaction tran)
 {
     if (tran == null && (!TransactionBoundConnectionManager.IsAmbientConnection(dbCon)))
     {
         try
         {
             if (dbCon.State != ConnectionState.Closed)
             {
                 dbCon.Close();
             }
         }
         catch
         {
             //Log error
         }
     }
 }
        internal static bool IsAmbientConnection(DbConnection currentCon)
        {
            bool        isAmbient = false;
            Transaction tran      = Transaction.Current;

            if (tran != null)
            {
                TransactionBoundConnectionManager tim = GetManager(tran);

                if (object.ReferenceEquals(tim._CurrentConnection, currentCon))
                {
                    isAmbient = true;
                }
            }

            return(isAmbient);
        }
        private static TransactionBoundConnectionManager GetManager(Transaction tran)
        {
            TransactionBoundConnectionManager tbcManager;
            string key = tran.TransactionInformation.LocalIdentifier;

            lock (_ActiveManagerLock)
            {
                if (_ActiveManagers.ContainsKey(key))
                {
                    tbcManager = _ActiveManagers[key];
                }
                else
                {
                    tbcManager = new TransactionBoundConnectionManager(tran);
                    tran.TransactionCompleted += new TransactionCompletedEventHandler(tbcManager.TransactionCompleted);
                    _ActiveManagers[key]       = tbcManager;
                }
            }
            return(tbcManager);
        }