public static void AddSubscribeSyncQueue <T>(
     this IServiceCollection services,
     RabbitConfiguration rabbitMQConfiguration,
     ICommandSyncHandler <T> handler)
 {
     AddSubscribeSyncQueue(handler,
                           rabbitMQConfiguration.HostName,
                           rabbitMQConfiguration.Port,
                           rabbitMQConfiguration.UserName,
                           rabbitMQConfiguration.Password,
                           rabbitMQConfiguration.ExchangeName,
                           rabbitMQConfiguration.ExchangeType,
                           rabbitMQConfiguration.RoutingKey,
                           rabbitMQConfiguration.QueueName,
                           rabbitMQConfiguration.NumberOfWorkroles,
                           rabbitMQConfiguration.CreateDeadLetterQueue);
 }
        private static void AddSubscribeSyncQueue <T>(
            ICommandSyncHandler <T> handler,
            string hostName,
            int port,
            string userName,
            string password,
            string exchangeName,
            string exchangeType,
            string routingKey,
            string queueName,
            int numberOfWorkroles,
            bool createDeadLetterQueue)
        {
            if (handler == null || string.IsNullOrEmpty(hostName) ||
                port < 1 ||
                string.IsNullOrEmpty(userName) ||
                string.IsNullOrEmpty(password) ||
                string.IsNullOrEmpty(exchangeName) ||
                string.IsNullOrEmpty(exchangeType) ||
                string.IsNullOrEmpty(routingKey) ||
                string.IsNullOrEmpty(queueName) ||
                numberOfWorkroles < 1)
            {
                throw new ArgumentException("A configuração do Subscribe do RabbitMQ está incorreta");
            }

            var factory = new ConnectionFactory()
            {
                HostName = hostName,
                Port     = port,
                UserName = userName,
                Password = password
            };

            factory.SubscribeSync(handler,
                                  exchangeName,
                                  exchangeType,
                                  routingKey,
                                  queueName,
                                  numberOfWorkroles, createDeadLetterQueue);
        }
        public static void AddSubscribeSyncQueue <T>(
            this IServiceCollection services,
            IConfiguration configuration,
            string configSectionRabbitMQHostConfiguration,
            string configSectionRabbitMQInfoQueueConfiguration,
            ICommandSyncHandler <T> handler)
        {
            var rabbitMQHostConfiguration = configuration.GetSection(configSectionRabbitMQHostConfiguration).Get <RabbitHostConfiguration>();

            var rabbitMQInfoQueueConfiguration = configuration.GetSection(configSectionRabbitMQInfoQueueConfiguration).Get <RabbitInfoQueueConfiguration>();

            AddSubscribeSyncQueue(handler,
                                  rabbitMQHostConfiguration.HostName,
                                  rabbitMQHostConfiguration.Port,
                                  rabbitMQHostConfiguration.UserName,
                                  rabbitMQHostConfiguration.Password,
                                  rabbitMQInfoQueueConfiguration.ExchangeName,
                                  rabbitMQInfoQueueConfiguration.ExchangeType,
                                  rabbitMQInfoQueueConfiguration.RoutingKey,
                                  rabbitMQInfoQueueConfiguration.QueueName,
                                  rabbitMQInfoQueueConfiguration.NumberOfWorkroles,
                                  rabbitMQInfoQueueConfiguration.CreateDeadLetterQueue);
        }
        internal static void SubscribeSync <T>(this ConnectionFactory connectionFactory, ICommandSyncHandler <T> handler, string exchangeName, string exchangeType, string routingKey, string queueName, int numberOfWorkroles, bool createDeadLetterQueue)
        {
            var connection = connectionFactory.CreateConnection();
            var channel    = connection.CreateModel();

            channel.ExchangeDeclare(exchange: exchangeName, type: exchangeType, durable: true);

            Dictionary <string, object> args = null;

            if (createDeadLetterQueue)
            {
                args = channel.CreateDeadLetterQueue($"{exchangeName}-dead", $"{routingKey}-dead", $"{queueName}-dead");
            }


            channel.QueueDeclare(queue: queueName, durable: true, exclusive: false, autoDelete: false, arguments: args);
            channel.QueueBind(queue: queueName, exchange: exchangeName, routingKey: routingKey);

            for (int i = 0; i < numberOfWorkroles; i++)
            {
                lock (channel)
                {
                    var consumer = new EventingBasicConsumer(channel)
                    {
                        ConsumerTag = Guid.NewGuid().ToString() // Tag de identificação do consumidor no RabbitMQ
                    };
                    consumer.Received += (sender, ea) =>
                    {
                        try
                        {
                            var mensagem = Encoding.UTF8.GetString(ea.Body);
                            var entidade = JsonConvert.DeserializeObject <T>(mensagem);
                            //Envia ao Handler a mensagem
                            handler.Handle(entidade);
                            //Diz ao RabbitMQ que a mensagem foi lida com sucesso pelo consumidor
                            channel.BasicAck(deliveryTag: ea.DeliveryTag, multiple: false);
                        }
                        catch (Exception ex)
                        {
                            Console.WriteLine(ex);
                            channel.BasicNack(ea.DeliveryTag, false, false);
                        }
                    };
                    //Registra os consumidor no RabbitMQ
                    channel.BasicConsume(queueName, false, consumer: consumer);
                }
            }
        }