/// <summary>Create a bare channel.</summary>
        /// <param name="transactional">The transactional.</param>
        /// <returns>The bare channel.</returns>
        internal IModel CreateBareChannel(bool transactional)
        {
            if (this.connection == null || !this.connection.IsOpen())
            {
                this.connection = null;

                // Use CreateConnection here not DoCreateConnection so that the old one is properly disposed
                this.CreateConnection();
            }

            var channel = this.connection.CreateBareChannel(transactional);

            if (this.publisherConfirms)
            {
                try
                {
                    channel.ConfirmSelect();
                }
                catch (Exception ex)
                {
                    Logger.Error(m => m("Could not configure the channel to receive publisher confirms"), ex);
                }
            }

            if (this.publisherConfirms || this.publisherReturns)
            {
                if (!(channel is PublisherCallbackChannelImpl))
                {
                    channel = new PublisherCallbackChannelImpl(channel);
                }
            }

            return(channel);
        }
        /// <summary>
        /// Reset the Channel cache and underlying shared Connection, to be reinitialized on next access.
        /// </summary>
        public override void Dispose()
        {
            lock (this.connectionMonitor)
            {
                if (this.connection != null)
                {
                    this.connection.Dispose();
                    this.connection = null;
                }
            }

            this.Reset();
        }
        /// <summary>
        /// Create a connection.
        /// </summary>
        /// <returns>The connection.</returns>
        public override IConnection CreateConnection()
        {
            lock (this.connectionMonitor)
            {
                if (this.connection == null)
                {
                    this.connection = new ChannelCachingConnectionProxy(this.CreateBareConnection(), this);

                    // invoke the listener *after* this.connection is assigned
                    this.ConnectionListener.OnCreate(this.connection);
                }
            }

            return(this.connection);
        }
        /// <summary>
        /// Resets this instance.
        /// </summary>
        internal void Reset()
        {
            this.active = false;
            lock (this.cachedChannelsNonTransactional)
            {
                foreach (var channel in this.cachedChannelsNonTransactional)
                {
                    try
                    {
                        channel.GetTargetChannel().Close();
                    }
                    catch (Exception ex)
                    {
                        Logger.Trace("Could not close cached Rabbit Channel", ex);
                    }
                }

                this.cachedChannelsNonTransactional.Clear();
            }

            lock (this.cachedChannelsTransactional)
            {
                foreach (var channel in this.cachedChannelsTransactional)
                {
                    try
                    {
                        channel.GetTargetChannel().Close();
                    }
                    catch (Exception ex)
                    {
                        Logger.Trace("Could not close cached Rabbit Channel", ex);
                    }
                }

                this.cachedChannelsTransactional.Clear();
            }

            this.active     = true;
            this.connection = null;
        }
        /// <summary>
        /// Resets this instance.
        /// </summary>
        internal void Reset()
        {
            this.active = false;
            lock (this.cachedChannelsNonTransactional)
            {
                foreach (var channel in this.cachedChannelsNonTransactional)
                {
                    try
                    {
                        channel.GetTargetChannel().Close();
                    }
                    catch (Exception ex)
                    {
                        Logger.Trace("Could not close cached Rabbit Channel", ex);
                    }
                }

                this.cachedChannelsNonTransactional.Clear();
            }

            lock (this.cachedChannelsTransactional)
            {
                foreach (var channel in this.cachedChannelsTransactional)
                {
                    try
                    {
                        channel.GetTargetChannel().Close();
                    }
                    catch (Exception ex)
                    {
                        Logger.Trace("Could not close cached Rabbit Channel", ex);
                    }
                }

                this.cachedChannelsTransactional.Clear();
            }

            this.active = true;
            this.connection = null;
        }
        /// <summary>
        /// Reset the Channel cache and underlying shared Connection, to be reinitialized on next access.
        /// </summary>
        public override void Dispose()
        {
            lock (this.connectionMonitor)
            {
                if (this.connection != null)
                {
                    this.connection.Dispose();
                    this.connection = null;
                }
            }

            this.Reset();
        }
        /// <summary>
        /// Create a connection.
        /// </summary>
        /// <returns>The connection.</returns>
        public override IConnection CreateConnection()
        {
            lock (this.connectionMonitor)
            {
                if (this.connection == null)
                {
                    this.connection = new ChannelCachingConnectionProxy(this.CreateBareConnection(), this);

                    // invoke the listener *after* this.connection is assigned
                    this.ConnectionListener.OnCreate(this.connection);
                }
            }

            return this.connection;
        }
        /// <summary>Create a bare channel.</summary>
        /// <param name="transactional">The transactional.</param>
        /// <returns>The bare channel.</returns>
        internal IModel CreateBareChannel(bool transactional)
        {
            if (this.connection == null || !this.connection.IsOpen())
            {
                this.connection = null;

                // Use CreateConnection here not DoCreateConnection so that the old one is properly disposed
                this.CreateConnection();
            }

            var channel = this.connection.CreateBareChannel(transactional);

            if (this.publisherConfirms)
            {
                try
                {
                    channel.ConfirmSelect();
                }
                catch (Exception ex)
                {
                    Logger.Error(m => m("Could not configure the channel to receive publisher confirms"), ex);
                }
            }

            if (this.publisherConfirms || this.publisherReturns)
            {
                if (!(channel is PublisherCallbackChannelImpl))
                {
                    channel = new PublisherCallbackChannelImpl(channel);
                }
            }

            return channel;
        }
 /// <summary>
 /// Create a connection.
 /// </summary>
 /// <returns>
 /// The connection.
 /// </returns>
 protected override IConnection DoCreateConnection()
 {
     this.targetConnection = new ChannelCachingConnectionProxy(base.DoCreateConnection(), this);
     return this.targetConnection;
 }
        /// <summary>
        /// Reset the Channel cache and underlying shared Connection, to be reinitialized on next access.
        /// </summary>
        public override void Dispose()
        {
            this.active = false;
            lock (this.cachedChannelsNonTransactional)
            {
                foreach (var channel in this.cachedChannelsNonTransactional)
                {
                    try
                    {
                        channel.GetTargetChannel().Close();
                    }
                    catch (Exception ex)
                    {
                        logger.Trace("Could not close cached Rabbit Channel", ex);
                    }
                }
                this.cachedChannelsNonTransactional.Clear();
            }

            this.active = true;
            base.Dispose();
            this.targetConnection = null;
        }