/// <summary>
        /// Gets a shared, managed <see cref="ISenderClient" /> instance that is used to submit request messages.
        /// </summary>
        /// <typeparam name="TRequestMessage">
        /// The type of the request message.
        /// </typeparam>
        /// <typeparam name="TResponseMessage">
        /// The type of the response message.
        /// </typeparam>
        /// <returns>
        /// The managed <see cref="ISenderClient" /> instance.
        /// </returns>
        /// <exception cref="MessagePublishingException">
        /// An exception was raised while creating the send client.
        /// </exception>
        /// <exception cref="MessageSubscriptionException">
        /// An exception was raised while creating the receive client.
        /// </exception>
        /// <exception cref="ObjectDisposedException">
        /// The object is disposed.
        /// </exception>
        public ISenderClient GetRequestClient <TRequestMessage, TResponseMessage>()
            where TRequestMessage : class, IRequestMessage <TResponseMessage>
            where TResponseMessage : class, IResponseMessage
        {
            var requestMessageEntityType  = MessagePublishingClient.RequestMessageEntityType;
            var responseMessageEntityType = MessageSubscriptionClient.ResponseMessageEntityType;
            var responseMessageEntityPath = GetEntityPath <TResponseMessage>(responseMessageEntityType);
            var requestMessageSendClient  = GetSendClient <TRequestMessage>(requestMessageEntityType);

            using (var controlToken = StateControl.Enter())
            {
                RejectIfDisposed();

                if (SendClientDictionary.ContainsKey(responseMessageEntityPath) == false)
                {
                    var responseMessageSendClient = ClientFactory.CreateSendClient <TResponseMessage>(responseMessageEntityType);
                    SendClientDictionary.Add(responseMessageEntityPath, responseMessageSendClient);
                }

                if (ReceiveClientDictionary.ContainsKey(responseMessageEntityPath) == false)
                {
                    var responseMessageReceiveClient = ClientFactory.CreateReceiveClient <TResponseMessage>(responseMessageEntityType);
                    responseMessageReceiveClient.RegisterMessageHandler(HandleResponseMessage, ReceiverOptionsForResponseMessages);
                    ReceiveClientDictionary.Add(responseMessageEntityPath, responseMessageReceiveClient);
                }
            }

            return(requestMessageSendClient);
        }
        /// <summary>
        /// Gets a shared, managed <see cref="ISenderClient" /> instance.
        /// </summary>
        /// <typeparam name="TMessage">
        /// The type of the message that the client handles.
        /// </typeparam>
        /// <param name="entityType">
        /// The type of the entity.
        /// </param>
        /// <returns>
        /// The managed <see cref="ISenderClient" /> instance.
        /// </returns>
        /// <exception cref="ArgumentOutOfRangeException">
        /// <paramref name="entityType" /> is equal to <see cref="MessagingEntityType.Unspecified" />.
        /// </exception>
        /// <exception cref="MessagePublishingException">
        /// An exception was raised while creating the client.
        /// </exception>
        /// <exception cref="ObjectDisposedException">
        /// The object is disposed.
        /// </exception>
        public ISenderClient GetSendClient <TMessage>(MessagingEntityType entityType)
            where TMessage : class
        {
            var entityPath = GetEntityPath <TMessage>(entityType);

            using (var controlToken = StateControl.Enter())
            {
                RejectIfDisposed();

                if (SendClientDictionary.TryGetValue(entityPath, out var client))
                {
                    return(client);
                }

                client = ClientFactory.CreateSendClient <TMessage>(entityType);
                SendClientDictionary.Add(entityPath, client);
                return(client);
            }
        }