private async Task FuturePublishInternalAsync <T>(TimeSpan messageDelay, T message, string cancellationKey = null) where T : class { Preconditions.CheckNotNull(message, "message"); Preconditions.CheckLess(messageDelay, MaxMessageDelay, "messageDelay"); Preconditions.CheckNull(cancellationKey, "cancellationKey"); var exchangeName = conventions.ExchangeNamingConvention(typeof(T)); var futureExchangeName = exchangeName + "_delayed"; var queueName = conventions.QueueNamingConvention(typeof(T), null); var futureExchange = await advancedBus.ExchangeDeclareAsync(futureExchangeName, ExchangeType.Direct, delayed : true).ConfigureAwait(false); var exchange = await advancedBus.ExchangeDeclareAsync(exchangeName, ExchangeType.Topic).ConfigureAwait(false); await advancedBus.BindAsync(futureExchange, exchange, "#").ConfigureAwait(false); var queue = await advancedBus.QueueDeclareAsync(queueName).ConfigureAwait(false); await advancedBus.BindAsync(exchange, queue, "#").ConfigureAwait(false); var easyNetQMessage = new Message <T>(message) { Properties = { DeliveryMode = messageDeliveryModeStrategy.GetDeliveryMode(typeof(T)), Headers = new Dictionary <string, object>{ { "x-delay", (int)messageDelay.TotalMilliseconds } } } }; await advancedBus.PublishAsync(futureExchange, "#", false, false, easyNetQMessage).ConfigureAwait(false); }
public Task FuturePublishAsync <T>(TimeSpan messageDelay, T message) where T : class { Preconditions.CheckNotNull(message, "message"); Preconditions.CheckLess(messageDelay, MaxMessageDelay, "messageDelay"); var delay = Round(messageDelay); var delayString = delay.ToString(@"dd\_hh\_mm\_ss"); var exchangeName = conventions.ExchangeNamingConvention(typeof(T)); var futureExchangeName = exchangeName + "_" + delayString; var futureQueueName = conventions.QueueNamingConvention(typeof(T), delayString); return(advancedBus.ExchangeDeclareAsync(futureExchangeName, ExchangeType.Topic) .Then(futureExchange => advancedBus.QueueDeclareAsync(futureQueueName, perQueueTtl: (int)delay.TotalMilliseconds, deadLetterExchange: exchangeName) .Then(futureQueue => advancedBus.BindAsync(futureExchange, futureQueue, "#")) .Then(() => { var easyNetQMessage = new Message <T>(message) { Properties = { DeliveryMode = (byte)(messageDeliveryModeStrategy.IsPersistent(typeof(T)) ? 2 : 1) } }; return advancedBus.PublishAsync(futureExchange, "#", false, false, easyNetQMessage); }))); }
public async Task <IDisposable> AddSubscription <TEvent>(string sourceBoundedContextName, string publishedLanguageEntity) where TEvent : class { var queue = await _messageBus.QueueDeclareAsync(NamingConventions.QueueNamingConvention(_boundedContextName, sourceBoundedContextName, publishedLanguageEntity, _subscriberId)); await _messageBus.BindAsync( new Exchange( NamingConventions.ExchangeNamingConvention(sourceBoundedContextName, publishedLanguageEntity)), queue, ""); return(_messageBus.Consume(queue, async(bytes, properties, info) => { var msg = Encoding.UTF8.GetString(bytes); Console.WriteLine(msg); var validationResult = await _schemaValidator.IsValid <TEvent>(msg); if (validationResult.IsValid) { var envelope = System.Text.Json.JsonSerializer.Deserialize <Envelope <TEvent> >(msg); var props = new MessageProperties(); properties.CopyTo(props); await _eventDispatcher.HandleEvent(envelope, props); } else { throw new Exception($"Schema is invalid, errors: {string.Join(", ", validationResult.Errors)}"); } })); }
private async Task FuturePublishInternalAsync <T>(TimeSpan messageDelay, T message, string cancellationKey) where T : class { Preconditions.CheckNotNull(message, "message"); Preconditions.CheckLess(messageDelay, MaxMessageDelay, "messageDelay"); Preconditions.CheckNull(cancellationKey, "cancellationKey"); var delay = Round(messageDelay); var delayString = delay.ToString(@"dd\_hh\_mm\_ss"); var exchangeName = conventions.ExchangeNamingConvention(typeof(T)); var futureExchangeName = exchangeName + "_" + delayString; var futureQueueName = conventions.QueueNamingConvention(typeof(T), delayString); var futureExchange = await advancedBus.ExchangeDeclareAsync(futureExchangeName, ExchangeType.Topic).ConfigureAwait(false); var futureQueue = await advancedBus.QueueDeclareAsync(futureQueueName, perQueueMessageTtl : (int)delay.TotalMilliseconds, deadLetterExchange : exchangeName).ConfigureAwait(false); await advancedBus.BindAsync(futureExchange, futureQueue, "#").ConfigureAwait(false); var easyNetQMessage = new Message <T>(message) { Properties = { DeliveryMode = messageDeliveryModeStrategy.GetDeliveryMode(typeof(T)) } }; await advancedBus.PublishAsync(futureExchange, "#", false, false, easyNetQMessage).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 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); }
/// <summary> /// Bind an exchange to a queue. Does nothing if the binding already exists. /// </summary> /// <param name="bus">The bus instance</param> /// <param name="exchange">The exchange to bind</param> /// <param name="queue">The queue to bind</param> /// <param name="routingKey">The routing key</param> /// <param name="cancellationToken">The cancellation token</param> /// <returns>A binding</returns> public static IBinding Bind(this IAdvancedBus bus, IExchange exchange, IQueue queue, string routingKey, CancellationToken cancellationToken = default) { Preconditions.CheckNotNull(bus, "bus"); return(bus.BindAsync(exchange, queue, routingKey, cancellationToken) .GetAwaiter() .GetResult()); }
/// <summary> /// Creates a queue and its associated exchange on the message broker. If the associated /// exchange is the RabbitMQ default exchange, only the queue is created. For a non-default /// exchange, the queue is bound to the exchange. If the metadata has route-keys specified, /// the queue is bound the to exchange for each specified key. /// </summary> /// <param name="bus">Reference to the advanced bus.</param> /// <param name="meta">The metadata describing the queue.</param> /// <returns>Reference to the created queue.</returns> public static async Task <IQueue> QueueDeclare(this IAdvancedBus bus, QueueMeta meta) { if (bus == null) { throw new ArgumentNullException(nameof(bus)); } if (meta == null) { throw new ArgumentNullException(nameof(meta)); } IExchange exchange = Exchange.GetDefault(); // Assume default exchange. ExchangeMeta exchangeMeta = meta.Exchange; if (!meta.Exchange.IsDefaultExchange) { exchange = await bus.ExchangeDeclareAsync(exchangeMeta.ExchangeName, exchangeMeta.ExchangeType, durable : exchangeMeta.IsDurable, autoDelete : exchangeMeta.IsAutoDelete, passive : exchangeMeta.IsPassive, alternateExchange : exchangeMeta.AlternateExchangeName); } IQueue queue = await bus.QueueDeclareAsync(meta.ScopedQueueName, durable : meta.IsDurable, autoDelete : meta.IsAutoDelete, exclusive : meta.IsExclusive, passive : meta.IsPassive, maxPriority : meta.MaxPriority, deadLetterExchange : meta.DeadLetterExchange, deadLetterRoutingKey : meta.DeadLetterRoutingKey, perQueueMessageTtl : meta.PerQueueMessageTtl); // Queues defined on the default exchange so don't bind. if (exchangeMeta.IsDefaultExchange) { return(queue); } string[] routeKeys = meta.RouteKeys ?? new string[] { }; if (routeKeys.Length > 0) { // If route-keys specified, bind the queue to the exchange // for each route-key. foreach (string routeKey in meta.RouteKeys ?? new string[] {}) { bus.Bind(exchange, queue, routeKey); } } else { await bus.BindAsync(exchange, queue, string.Empty); } return(queue); }
/// <summary> /// Bind two exchanges. Does nothing if the binding already exists. /// </summary> /// <param name="bus">The bus instance</param> /// <param name="source">The source exchange</param> /// <param name="destination">The destination exchange</param> /// <param name="routingKey">The routing key</param> /// <param name="cancellationToken">The cancellation token</param> /// <returns>A binding</returns> public static Task <IBinding> BindAsync( this IAdvancedBus bus, IExchange source, IExchange destination, string routingKey, CancellationToken cancellationToken ) { Preconditions.CheckNotNull(bus, "bus"); return(bus.BindAsync(source, destination, routingKey, null, cancellationToken)); }
private async Task <EasyNetQ.Topology.IExchange> BindExchangeWithMessageQueueAsync(string exchangename) { _logger.LogDebug("BindExchangeWithMessageQueueAsync() started."); var exchange = await _advancedBus.ExchangeDeclareAsync(exchangename, ExchangeType.Topic); var queue = await InitializeGetQueuesAsync(); var binding = await _advancedBus.BindAsync(exchange, queue, string.Empty); _logger.LogDebug("BindExchangeWithMessageQueueAsync() completed."); return(exchange); }
private async Task <string> SubscribeToReplyAsync(CancellationToken cancellationToken) { if (_replyQueue != null) { return(_replyQueue); } using (await _replyQueueLock.AcquireAsync(cancellationToken)) { if (_replyQueue != null) { return(_replyQueue); } var replyQueue = $"toxon.micro.rpc.reply.{Guid.NewGuid()}"; var exchange = await _bus.ExchangeDeclareAsync(ReplyExchangeName, ExchangeType.Direct); var queue = await _bus.QueueDeclareAsync(replyQueue); await _bus.BindAsync(exchange, queue, replyQueue); _bus.Consume(queue, (body, props, info) => { var correlationIdString = props.CorrelationId; if (Guid.TryParse(correlationIdString, out var correlationId) && _responseHandlers.TryRemove(correlationId, out var tcs)) { tcs.SetResult(MessageHelpers.FromArgs(body, props)); } }); _replyQueue = replyQueue; return(_replyQueue); } }
/// <summary> /// Bind two exchanges. Does nothing if the binding already exists. /// </summary> /// <param name="bus">The bus instance</param> /// <param name="source">The source exchange</param> /// <param name="destination">The destination exchange</param> /// <param name="routingKey">The routing key</param> /// <param name="headers">The headers</param> /// <param name="cancellationToken">The cancellation token</param> /// <returns>A binding</returns> public static IBinding Bind( this IAdvancedBus bus, IExchange source, IExchange destination, string routingKey, IDictionary <string, object> headers, CancellationToken cancellationToken = default ) { Preconditions.CheckNotNull(bus, "bus"); return(bus.BindAsync(source, destination, routingKey, headers, cancellationToken) .GetAwaiter() .GetResult()); }
private Task<IExchange> DeclareVersionedExchanges(IAdvancedBus advancedBus, IConventions conventions, MessageVersionStack messageVersions, string exchangeType) { var destinationExchangeTask = TaskHelpers.FromResult<IExchange>(null); while (! messageVersions.IsEmpty()) { var messageType = messageVersions.Pop(); var exchangeName = conventions.ExchangeNamingConvention(messageType); destinationExchangeTask = destinationExchangeTask.Then(destinationExchange => DeclareExchangeAsync(advancedBus, exchangeName, exchangeType).Then(sourceExchange => { if (destinationExchange != null) return advancedBus.BindAsync(sourceExchange, destinationExchange, "#").Then(() => sourceExchange); return TaskHelpers.FromResult(sourceExchange); })); } return destinationExchangeTask; }
/// <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); }
private async Task <IExchange> DeclareVersionedExchangesAsync(IAdvancedBus advancedBus, IConventions conventions, MessageVersionStack messageVersions, string exchangeType) { IExchange destinationExchange = null; while (!messageVersions.IsEmpty()) { var messageType = messageVersions.Pop(); var exchangeName = conventions.ExchangeNamingConvention(messageType); var sourceExchange = await DeclareExchangeAsync(advancedBus, exchangeName, exchangeType).ConfigureAwait(false); if (destinationExchange != null) { await advancedBus.BindAsync(sourceExchange, destinationExchange, "#").ConfigureAwait(false); } destinationExchange = sourceExchange; } return(destinationExchange); }
private Task <IExchange> DeclareVersionedExchanges(IAdvancedBus advancedBus, IConventions conventions, MessageVersionStack messageVersions, string exchangeType) { var destinationExchangeTask = TaskHelpers.FromResult <IExchange>(null); while (!messageVersions.IsEmpty()) { var messageType = messageVersions.Pop(); var exchangeName = conventions.ExchangeNamingConvention(messageType); destinationExchangeTask = destinationExchangeTask.Then(destinationExchange => DeclareExchangeAsync(advancedBus, exchangeName, exchangeType).Then(sourceExchange => { if (destinationExchange != null) { return(advancedBus.BindAsync(sourceExchange, destinationExchange, "#").Then(() => sourceExchange)); } return(TaskHelpers.FromResult(sourceExchange)); })); } return(destinationExchangeTask); }
public async Task DeclareAsync(CancellationToken cancellationToken) { _logger.LogInformation($"Entering {nameof(DeclareAsync)}"); try { var exchange = await _advancedBus.ExchangeDeclareAsync(name : _exchanges.ExchangeKey, type : ExchangeType.Direct, cancellationToken : cancellationToken).ConfigureAwait(false); var queue = await _advancedBus.QueueDeclareAsync(name : _queues.QueueKey, durable : true, exclusive : false, autoDelete : false, cancellationToken : cancellationToken).ConfigureAwait(false); await _advancedBus.BindAsync(exchange : exchange, queue : queue, routingKey : _routings.RoutingKey, headers : null, cancellationToken : cancellationToken).ConfigureAwait(false); _logger.LogInformation($"Bind - Exchange: {_exchanges.ExchangeKey}, Queue: {_queues.QueueKey}, RoutingKey: {_routings.RoutingKey}"); } catch (Exception ex) { _logger.LogError(ex, ex.Message); throw; } }
public async Task <IExchange> DeclareExchangeAsync(IAdvancedBus advancedBus, Type messageType, string exchangeType) { var conventions = advancedBus.Container.Resolve <IConventions>(); var sourceExchangeName = conventions.ExchangeNamingConvention(messageType); var sourceExchange = await DeclareExchangeAsync(advancedBus, sourceExchangeName, exchangeType).ConfigureAwait(false); var interfaces = messageType.GetInterfaces(); foreach (var @interface in interfaces) { var destinationExchangeName = conventions.ExchangeNamingConvention(@interface); var destinationExchange = await DeclareExchangeAsync(advancedBus, destinationExchangeName, exchangeType); if (destinationExchange != null) { await advancedBus.BindAsync(sourceExchange, destinationExchange, "#").ConfigureAwait(false); } } return(sourceExchange); }
public async Task SubscribeAsync(Func <string, CancellationToken, Task> processMessageAsync, CancellationToken cancellationToken) { _logger.LogInformation($"Entering {nameof(SubscribeAsync)}"); try { var exchange = await _advancedBus.ExchangeDeclareAsync(name : _exchanges.ExchangeKey, type : ExchangeType.Direct, cancellationToken : cancellationToken).ConfigureAwait(false); var queue = await _advancedBus.QueueDeclareAsync(name : _queues.QueueKey, durable : true, exclusive : false, autoDelete : false, cancellationToken : cancellationToken).ConfigureAwait(false); await _advancedBus.BindAsync(exchange : exchange, queue : queue, routingKey : _routings.RoutingKey, headers : null, cancellationToken : cancellationToken).ConfigureAwait(false); _advancedBus.Consume(queue, (body, _, _) => Task.Factory.StartNew(async() => { var message = Encoding.UTF8.GetString(body); await processMessageAsync(message, cancellationToken).ConfigureAwait(false); }, cancellationToken)); } catch (Exception ex) { _logger.LogError(ex, ex.Message); throw; } }
private async Task<IExchange> DeclareVersionedExchangesAsync(IAdvancedBus advancedBus, IConventions conventions, MessageVersionStack messageVersions, string exchangeType) { IExchange destinationExchange = null; while (! messageVersions.IsEmpty()) { var messageType = messageVersions.Pop(); var exchangeName = conventions.ExchangeNamingConvention(messageType); var sourceExchange = await DeclareExchangeAsync(advancedBus, exchangeName, exchangeType).ConfigureAwait(false); if (destinationExchange != null) { await advancedBus.BindAsync(sourceExchange, destinationExchange, "#").ConfigureAwait(false); } destinationExchange = sourceExchange; } return destinationExchange; }
private async Task <ISubscriber> CreateSubscriberAsync(string name, bool temporary, Action temporaryQueueDisconnected, IEnumerable <string> routings, int retrycount, int prefetchcount, bool explicitAcknowledgments, ISubscriptionSelector subscriptionSelector, bool storedeadletter) { if (string.IsNullOrEmpty(name)) { throw new ArgumentException("name argument can not be null or empty"); } if ((routings != null) && (routings.Any(routing => string.IsNullOrEmpty(routing)) || !routings.Any())) { throw new ArgumentException("routings argument can not be empty or contain empty strings"); } if (retrycount < 0) { throw new ArgumentException("retrycount argument can not be less than zero"); } if (temporaryQueueDisconnected != null) { _broker.RegisterDisconnectedAction(temporaryQueueDisconnected); } //Main subscriber queue and bindings var queue = await _bus.QueueDeclareAsync( _environmentNamingConventionController.GetQueueName(name), false, true, temporary); if (routings != null) { foreach (var routing in routings) { await _bus.BindAsync(await _exchange, queue, routing); } } //Retry subscriber queue and bindings for (int i = 1; i <= retrycount; i++) { var retryqueueroutingkey = _environmentNamingConventionController.GetRetryRoutingKey(name, i); var retryqueuequeuename = _environmentNamingConventionController.GetRetryQueueName(name, i); var queueretrybinding = await _bus.BindAsync(await _exchange, queue, retryqueueroutingkey); var retryqueue = await _bus.QueueDeclareAsync(retryqueuequeuename, false, true, temporary, false, _retryfactor *i, null, null, (await _exchange).Name); var retryqueuebinding = await _bus.BindAsync(_easyNetQPublisherToWaitExchange.Exchange, retryqueue, retryqueueroutingkey); } //Dead letter subscriber queue and bindings if (storedeadletter) { var deadletterqueueroutingkey = _environmentNamingConventionController .GetDeadLetterQueueRoutingKey(name); var deadletterqueuequeuename = _environmentNamingConventionController. GetDeadLetterQueueName(name); var deadletterqueue = await _bus.QueueDeclareAsync(deadletterqueuequeuename, false, true, temporary); var deadletterqueuebinding = await _bus.BindAsync(_easyNetQPublisherToWaitExchange.Exchange, deadletterqueue, deadletterqueueroutingkey); } //Direct Routing Key binding var directroutingkey = _environmentNamingConventionController.GetDirectRoutingKey(name); var queuedirectroutingkeybinding = await _bus.BindAsync(await _exchange, queue, directroutingkey); if (_subscriberController.RegisterSubscriberName(name, out IDisposable nameHandle)) { var executionHandler = new ExecutionHandlingStrategy(name, _easyNetQPublisherToWaitExchange, retrycount, _environmentNamingConventionController, explicitAcknowledgments, _publisher, storedeadletter); return(new EasyNetQSubscriber(executionHandler, _bus, queue, (ushort)prefetchcount, subscriptionSelector, executionHandler, nameHandle)); } else { throw new SubscriberAlreadyExistsException($"The subscriber " + $"with name {name}" + $" already exists"); } }
private async Task <ISubscriptionResult> SubscribeAsyncInternal <T>( string subscriptionId, Func <T, CancellationToken, Task> onMessage, Action <ISubscriptionConfiguration> configure, CancellationToken cancellationToken ) { using var cts = cancellationToken.WithTimeout(configuration.Timeout); var subscriptionConfiguration = new SubscriptionConfiguration(configuration.PrefetchCount); configure(subscriptionConfiguration); var queueName = subscriptionConfiguration.QueueName ?? conventions.QueueNamingConvention(typeof(T), subscriptionId); var exchangeName = conventions.ExchangeNamingConvention(typeof(T)); var queue = await advancedBus.QueueDeclareAsync( queueName, c => { c.AsDurable(subscriptionConfiguration.Durable); c.AsAutoDelete(subscriptionConfiguration.AutoDelete); if (subscriptionConfiguration.Expires.HasValue) { c.WithExpires(TimeSpan.FromMilliseconds(subscriptionConfiguration.Expires.Value)); } if (subscriptionConfiguration.MaxPriority.HasValue) { c.WithMaxPriority(subscriptionConfiguration.MaxPriority.Value); } if (subscriptionConfiguration.MaxLength.HasValue) { c.WithMaxLength(subscriptionConfiguration.MaxLength.Value); } if (subscriptionConfiguration.MaxLengthBytes.HasValue) { c.WithMaxLengthBytes(subscriptionConfiguration.MaxLengthBytes.Value); } if (!string.IsNullOrEmpty(subscriptionConfiguration.QueueMode)) { c.WithQueueMode(subscriptionConfiguration.QueueMode); } }, cts.Token ).ConfigureAwait(false); var exchange = await advancedBus.ExchangeDeclareAsync(exchangeName, ExchangeType.Topic, cancellationToken : cts.Token).ConfigureAwait(false); foreach (var topic in subscriptionConfiguration.Topics.DefaultIfEmpty("#")) { await advancedBus.BindAsync(exchange, queue, topic, cts.Token).ConfigureAwait(false); } var consumerCancellation = advancedBus.Consume <T>( queue, (message, messageReceivedInfo) => onMessage(message.Body, default), x => x.WithPriority(subscriptionConfiguration.Priority) .WithPrefetchCount(subscriptionConfiguration.PrefetchCount) .WithExclusive(subscriptionConfiguration.IsExclusive) ); return(new SubscriptionResult(exchange, queue, consumerCancellation)); }