/// <inheritdoc />
        public async Task FuturePublishAsync <T>(
            T message,
            TimeSpan delay,
            Action <IFuturePublishConfiguration> configure,
            CancellationToken cancellationToken = default
            )
        {
            Preconditions.CheckNotNull(message, "message");
            Preconditions.CheckNotNull(configure, "configure");

            using var cts = cancellationToken.WithTimeout(configuration.Timeout);

            var publishConfiguration = new FuturePublishConfiguration(conventions.TopicNamingConvention(typeof(T)));

            configure(publishConfiguration);

            var topic    = publishConfiguration.Topic;
            var exchange = await exchangeDeclareStrategy.DeclareExchangeAsync(
                conventions.ExchangeNamingConvention(typeof(T)),
                ExchangeType.Topic,
                cts.Token
                ).ConfigureAwait(false);

            var delayString    = delay.ToString(@"dd\_hh\_mm\_ss");
            var futureExchange = await exchangeDeclareStrategy.DeclareExchangeAsync(
                $"{conventions.ExchangeNamingConvention(typeof(T))}_{delayString}",
                ExchangeType.Topic,
                cts.Token
                ).ConfigureAwait(false);

            var futureQueue = await advancedBus.QueueDeclareAsync(
                conventions.QueueNamingConvention(typeof(T), delayString),
                c =>
            {
                c.WithMessageTtl(delay);
                c.WithDeadLetterExchange(exchange);
                if (setDeadLetterRoutingKey)
                {
                    c.WithDeadLetterRoutingKey(topic);
                }
            },
                cts.Token
                ).ConfigureAwait(false);

            await advancedBus.BindAsync(futureExchange, futureQueue, topic, cts.Token).ConfigureAwait(false);

            var properties = new MessageProperties();

            if (publishConfiguration.Priority != null)
            {
                properties.Priority = publishConfiguration.Priority.Value;
            }
            properties.DeliveryMode = messageDeliveryModeStrategy.GetDeliveryMode(typeof(T));

            var advancedMessage = new Message <T>(message, properties);
            await advancedBus.PublishAsync(
                futureExchange, topic, configuration.MandatoryPublish, advancedMessage, cts.Token
                ).ConfigureAwait(false);
        }
        /// <inheritdoc />
        public async Task FuturePublishAsync <T>(
            T message,
            TimeSpan delay,
            Action <IFuturePublishConfiguration> configure,
            CancellationToken cancellationToken = default
            )
        {
            Preconditions.CheckNotNull(message, "message");
            Preconditions.CheckNotNull(configure, "configure");

            using var cts = cancellationToken.WithTimeout(configuration.Timeout);

            var publishConfiguration = new FuturePublishConfiguration(conventions.TopicNamingConvention(typeof(T)));

            configure(publishConfiguration);

            var topic              = publishConfiguration.Topic;
            var exchangeName       = conventions.ExchangeNamingConvention(typeof(T));
            var futureExchangeName = exchangeName + "_delayed";
            var futureExchange     = await advancedBus.ExchangeDeclareAsync(
                futureExchangeName,
                c => c.AsDelayedExchange(ExchangeType.Topic),
                cts.Token
                ).ConfigureAwait(false);

            var exchange = await advancedBus.ExchangeDeclareAsync(
                exchangeName,
                c => c.WithType(ExchangeType.Topic),
                cts.Token
                ).ConfigureAwait(false);

            await advancedBus.BindAsync(futureExchange, exchange, topic, cts.Token).ConfigureAwait(false);

            var properties = new MessageProperties();

            if (publishConfiguration.Priority != null)
            {
                properties.Priority = publishConfiguration.Priority.Value;
            }
            properties.DeliveryMode = messageDeliveryModeStrategy.GetDeliveryMode(typeof(T));

            await advancedBus.PublishAsync(
                futureExchange, topic, false, new Message <T>(message, properties).WithDelay(delay), cts.Token
                ).ConfigureAwait(false);
        }