private string EnsureQueueExists(string queueName, RabbitWorkQueueMode mode, IDictionary <string, object> queueArgs = null)
        {
            queueName = queueName ?? "";

            using (var ch = CreateChannel())
            {
                // try to create queue
                try
                {
                    var res = ch.QueueDeclare(queue: queueName ?? "",
                                              durable: mode == RabbitWorkQueueMode.OpenOrCreatePersistent,
                                              exclusive: false,
                                              autoDelete: mode == RabbitWorkQueueMode.OpenOrCreateTemporary,
                                              arguments: queueArgs);

                    // set queue name if a random one was generated
                    if (String.IsNullOrEmpty(queueName) && res != null)
                    {
                        queueName = res.QueueName;
                    }
                }
                catch { }
            }
            return(queueName);
        }
        private void Initialize(string address, int port, string username, string password, string queueName, ushort batchSize, RabbitWorkQueueMode mode, int retryDelayMilliseconds, int maxRetry)
        {
            QueueName  = queueName;
            Mode       = mode;
            _batchSize = batchSize;
            _retryDelayMilliseconds = retryDelayMilliseconds;
            _maxRetry = maxRetry;

            // open connection and channel
            _factory = new RabbitConnectionFactory(address, port, username, password);

            // create our channels
            _publishChannel  = CreateChannel();
            _consumerChannel = CreateChannel();

            // publish mode
            _publishPersistent = mode == RabbitWorkQueueMode.OpenOrCreatePersistent || mode == RabbitWorkQueueMode.OpenPersistent;

            // create queue (only if not exists)
            if (mode != RabbitWorkQueueMode.OpenPersistent && mode != RabbitWorkQueueMode.OpenInMemory)
            {
                if (String.IsNullOrEmpty(queueName))
                {
                    queueName = "temp_" + System.IO.Path.GetRandomFileName().Replace(".", "") + "_" + DateTime.UtcNow.ToString("yyyyMMdd");
                }

                // declare delayed exchange
                if (retryDelayMilliseconds > 0)
                {
                    delayedExchange = queueName + ".delayed";
                    SafeExecute(c => c.ExchangeDeclare(delayedExchange, "x-delayed-message", true, true, CreateProperty("x-delayed-type", "direct")));
                }

                // create dead letter queue
                // note: dead-letter queue will be create only if needed

                // check if queue already exists
                var args = new Dictionary <string, object> ();
                args.AddProperty("x-dead-letter-exchange", delayedExchange ?? "");
                // args.AddProperty ("x-dead-letter-routing-key", queueName);

                QueueName = EnsureQueueExists(queueName, mode, args);

                // bind together exchanges to queue
                SafeExecute(c => c.QueueBind(QueueName, delayedExchange, QueueName));
            }
        }
        /// <summary>
        /// Initializes a new instance of the <see cref="RabbitWorkQueue" /> class.
        /// </summary>
        /// <param name="queueUri">The queue URI address formated as amqp://login:password@address:port</param>
        /// <param name="queueName">Queue name. If empty, a temporary queue with a random queue name will be created.</param>
        /// <param name="batchSize">Maximum number of unacknowledged messages for this connection. This helps to improve throughput as multiple messages are received for each request. Use '0' for ilimited.</param>
        /// <param name="mode">How to handle queue creation and message publishing.</param>
        /// <param name="retryDelayMilliseconds">The retry delay milliseconds. In case of failed message (Nack) will wait the retry delay before becoming available again.</param>
        /// <param name="maxRetry">The max retry for failed (Nack) messages.</param>
        public RabbitWorkQueue(string queueUri, string queueName, ushort batchSize = 10, RabbitWorkQueueMode mode = RabbitWorkQueueMode.OpenOrCreateInMemory, int retryDelayMilliseconds = 0, int maxRetry = 0)
        {
            if (queueUri.IndexOf("://") < 0)
            {
                queueUri = "amqp://" + queueUri;
            }

            var uri  = new Uri(queueUri);
            var auth = uri.UserInfo.Split(':');

            Initialize(uri.Host, uri.Port > 0 ? uri.Port : 5672, auth[0], auth.Length > 1 ? auth[1] : "", queueName, batchSize, mode, retryDelayMilliseconds, maxRetry);
        }
 /// <summary>
 /// Initializes a new instance of the <see cref="RabbitWorkQueue" /> class.
 /// </summary>
 /// <param name="address">RabbitMQ address.</param>
 /// <param name="port">RabbitMQ server port. Defaults to 5672.</param>
 /// <param name="username">RabbitMQ username.</param>
 /// <param name="password">RabbitMQ password.</param>
 /// <param name="queueName">Queue name. If empty, a temporary queue with a random queue name will be created.</param>
 /// <param name="batchSize">Maximum number of unacknowledged messages for this connection. This helps to improve throughput as multiple messages are received for each request. Use '0' for ilimited.</param>
 /// <param name="mode">How to handle queue creation and message publishing.</param>
 /// <param name="retryDelayMilliseconds">The retry delay milliseconds. In case of failed message (Nack) will wait the retry delay before becoming available again.</param>
 /// <param name="maxRetry">The max retry for failed (Nack) messages.</param>
 public RabbitWorkQueue(string address, int port, string username, string password, string queueName, ushort batchSize = 10, RabbitWorkQueueMode mode = RabbitWorkQueueMode.OpenOrCreateInMemory, int retryDelayMilliseconds = 0, int maxRetry = 0)
 {
     Initialize(address, port, username, password, queueName, batchSize, mode, retryDelayMilliseconds, maxRetry);
 }