public async Task Send(string topic, ToposMessage message, string partitionKey = null, CancellationToken cancellationToken = default)
    {
        if (topic == null)
        {
            throw new ArgumentNullException(nameof(topic));
        }
        if (message == null)
        {
            throw new ArgumentNullException(nameof(message));
        }

        var transportMessage = GetTransportMessage(message);

        _logger.Debug("Sending message with ID {messageId} to topic {topic}", transportMessage.GetMessageId(), topic);

        await _producerImplementation.Send(topic, partitionKey, transportMessage, cancellationToken);
    }
        public async Task Send(object message, string partitionKey = null, Dictionary <string, string> optionalHeaders = null)
        {
            if (message == null)
            {
                throw new ArgumentNullException(nameof(message));
            }

            var topic   = _topicMapper.GetTopic(message);
            var headers = optionalHeaders ?? new Dictionary <string, string>();

            if (!headers.ContainsKey(ToposHeaders.MessageId))
            {
                headers[ToposHeaders.MessageId] = Guid.NewGuid().ToString();
            }

            var logicalMessage   = new LogicalMessage(headers, message);
            var transportMessage = _messageSerializer.Serialize(logicalMessage);

            _logger.Debug("Sending message with ID {messageId} to topic {topic}", logicalMessage.GetMessageId(), topic);

            await _producerImplementation.Send(topic, partitionKey ?? "", transportMessage);
        }