/// <summary>
 /// Adds the <see cref="IConsumer"/>.
 /// </summary>
 /// <param name="builder">The <see cref="IActiveMqBuilder"/>.</param>
 /// <param name="address">The address name.</param>
 /// <param name="routingType">The routing type of the address.</param>
 /// <param name="queue">The queue name.</param>
 /// <param name="consumerOptions">The <see cref="IConsumer"/> configuration.</param>
 /// <param name="handler">A delegate that will be invoked when messages arrive.</param>
 /// <returns>The <see cref="IActiveMqBuilder"/> that can be used to configure ActiveMQ Artemis Client.</returns>
 public static IActiveMqBuilder AddConsumer(this IActiveMqBuilder builder, string address, RoutingType routingType, string queue, ConsumerOptions consumerOptions,
                                            Func <Message, IConsumer, IServiceProvider, CancellationToken, Task> handler)
 {
     return(builder.AddConsumer(address, routingType, queue, consumerOptions, new QueueOptions(), handler));
 }
        /// <summary>
        /// Adds the <see cref="IConsumer"/>.
        /// </summary>
        /// <param name="builder">The <see cref="IActiveMqBuilder"/>.</param>
        /// <param name="address">The address name.</param>
        /// <param name="routingType">The routing type of the address.</param>
        /// <param name="queue">The queue name.</param>
        /// <param name="consumerOptions">The <see cref="IConsumer"/> configuration.</param>
        /// <param name="queueOptions">The queue configuration that will be used when queue declaration is enabled.</param>
        /// <param name="handler">A delegate that will be invoked when messages arrive.</param>
        /// <returns>The <see cref="IActiveMqBuilder"/> that can be used to configure ActiveMQ Artemis Client.</returns>
        public static IActiveMqBuilder AddConsumer(this IActiveMqBuilder builder, string address, RoutingType routingType, string queue, ConsumerOptions consumerOptions, QueueOptions queueOptions,
                                                   Func <Message, IConsumer, IServiceProvider, CancellationToken, Task> handler)
        {
            builder.Services.Configure <ActiveMqOptions>(builder.Name, options =>
            {
                options.QueueConfigurations.Add(new QueueConfiguration
                {
                    Address            = address,
                    RoutingType        = routingType,
                    Name               = queue,
                    Exclusive          = queueOptions.Exclusive,
                    FilterExpression   = queueOptions.FilterExpression,
                    GroupBuckets       = queueOptions.GroupBuckets,
                    GroupRebalance     = queueOptions.GroupRebalance,
                    MaxConsumers       = queueOptions.MaxConsumers,
                    AutoCreateAddress  = queueOptions.AutoCreateAddress,
                    PurgeOnNoConsumers = queueOptions.PurgeOnNoConsumers
                });
                if (options.AddressConfigurations.TryGetValue(address, out var routingTypes))
                {
                    routingTypes.Add(routingType);
                }
                else
                {
                    options.AddressConfigurations[address] = new HashSet <RoutingType> {
                        routingType
                    };
                }
            });
            for (int i = 0; i < consumerOptions.ConcurrentConsumers; i++)
            {
                builder.AddConsumer(new ConsumerConfiguration
                {
                    Address          = address,
                    Queue            = queue,
                    Credit           = consumerOptions.Credit,
                    FilterExpression = consumerOptions.FilterExpression,
                    NoLocalFilter    = consumerOptions.NoLocalFilter,
                }, observable =>
                {
                    observable.Address     = address;
                    observable.RoutingType = routingType;
                    observable.Queue       = queue;
                }, handler);
            }

            return(builder);
        }
        /// <summary>
        /// Adds the <see cref="IConsumer"/>.
        /// </summary>
        /// <param name="builder">The <see cref="IActiveMqBuilder"/>.</param>
        /// <param name="address">The address name.</param>
        /// <param name="routingType">The routing type of the address.</param>
        /// <param name="consumerOptions">The <see cref="IConsumer"/> configuration.</param>
        /// <param name="handler">A delegate that will be invoked when messages arrive.</param>
        /// <returns>The <see cref="IActiveMqBuilder"/> that can be used to configure ActiveMQ Artemis Client.</returns>
        public static IActiveMqBuilder AddConsumer(this IActiveMqBuilder builder, string address, RoutingType routingType, ConsumerOptions consumerOptions,
                                                   Func <Message, IConsumer, IServiceProvider, CancellationToken, Task> handler)
        {
            for (int i = 0; i < consumerOptions.ConcurrentConsumers; i++)
            {
                builder.AddConsumer(new ConsumerConfiguration
                {
                    Address          = address,
                    RoutingType      = routingType,
                    Credit           = consumerOptions.Credit,
                    FilterExpression = consumerOptions.FilterExpression,
                    NoLocalFilter    = consumerOptions.NoLocalFilter
                }, observable =>
                {
                    observable.Address     = address;
                    observable.RoutingType = routingType;
                }, handler);
            }

            return(builder);
        }