public AsyncEventHandler <BasicDeliverEventArgs> Dequeue(CancellationToken cancellationToken,
                                                                 Func <string, T, Task> callback)
        {
            cancellationToken.ThrowIfCancellationRequested();

            if (callback == null)
            {
                throw new ArgumentNullException(nameof(callback));
            }

            var channel = _messagingFactory.Initialize();

            return((model, ea) =>
            {
                cancellationToken.ThrowIfCancellationRequested();

                _logger.LogDebug("MESSAGING | RECEIVING NEW MESSAGE");

                var body = ea.Body;
                var raw = Encoding.UTF8.GetString(body);
                var retries = 0;

                _logger.LogDebug("MESSAGING | RAW MESSAGE: {raw}");

                Policy
                .Handle <Exception>()
                .Fallback((app) => { },
                          onFallback: (context, expcetion) =>
                {
                    _logger.LogDebug("MESSAGING | SOMETHING HAPPENED WHEN PROCESSING THE MESSAGE: {ex}",
                                     context.Message);

                    if (_messagingConfiguration.Retries <= retries)
                    {
                        return;
                    }

                    channel.BasicNack(ea.DeliveryTag, false, false);

                    _logger.LogDebug("MESSAGING | MESSAGE HAS BEEN NACKED");
                }).Execute(() =>
                {
                    retries = Retries(ea);

                    _logger.LogDebug("MESSAGING | THIS MESSAGE HAS BEEN PROCESSED { retries } TIMES");

                    var message = JsonConvert.DeserializeObject <T>(raw);

                    callback.Invoke(raw, message).ConfigureAwait(false).GetAwaiter().GetResult();

                    _logger.LogDebug("MESSAGING | MESSAGE WILL BE ACKED");

                    channel.BasicAck(ea.DeliveryTag, false);

                    _logger.LogDebug("MESSAGING | MESSAGE HAS BEEN ACKED");
                });

                return Task.CompletedTask;
            });
        }
        protected override Task ExecuteAsync(CancellationToken stoppingToken)
        {
            var channel  = _messagingFactory.Initialize();
            var consumer = new AsyncEventingBasicConsumer(channel);

            consumer.Received += _messagingService.Dequeue(stoppingToken, async(raw, message) =>
            {
                if (message == null)
                {
                    return;
                }

                using (_logger.BeginScope(Guid.NewGuid().ToString()))
                {
                    try
                    {
                        var content = JsonSerializer.Serialize(new PingPongExample()
                        {
                            Id      = message.Id++,
                            IsPing  = true,
                            Message = "Ping"
                        });


                        _messagingService.Queue(new Message()
                        {
                            Exchange   = _messagingConfiguration.Publishing.Exchange.Name,
                            RoutingKey = _messagingConfiguration.Publishing.Routingkey,
                            Content    = content
                        });

                        _logger.LogInformation("Send ping from consumer");
                    }
                    catch (Exception ex)
                    {
                        _logger.LogCritical($"HOST | CRITICAL ERROR: {ex}");

                        throw;
                    }
                }
            });

            _tag = channel.BasicConsume(_messagingConfiguration.Consuming.Queue, false, string.Empty, false, false,
                                        null, consumer);

            return(Task.CompletedTask);
        }