public MessageQueueConsumer(
            RabbitMqProvider rabbitMqProvider,
            // ReSharper disable once SuggestBaseTypeForParameter
            ILogger <MessageQueueConsumer> logger,
            IOptions <QueueOptions> queueOptionsMonitor,
            IServiceProvider sp
            )
        {
            this.rabbitMqProvider = rabbitMqProvider;

            var queueOptions = queueOptionsMonitor.Value;

            queueName = rabbitMqProvider.Channel.QueueDeclare(
                queueOptions.QueueName,
                queueOptions.Durable,
                queueOptions.Exclusive,
                queueOptions.AutoDelete
                ).QueueName;

            var handlers = bindHandlers();
            var consumer = new AsyncEventingBasicConsumer(rabbitMqProvider.Channel);

            consumer.Received += async(sender, @event) => {
                try {
                    logger.LogDebug("Received event {eventName}", @event.RoutingKey);

                    using var scope = sp.CreateScope();

                    var tasks = new List <Task>();

                    foreach (var(handlerType, handlerMethod, parser) in handlers[@event.RoutingKey])
                    {
                        var handlerClass = scope.ServiceProvider.GetRequiredService(handlerType);

                        tasks.Add(
                            (Task)handlerMethod.Invoke(handlerClass,
                                                       // ReSharper disable once CoVariantArrayConversion
                                                       new[] { parser.ParseFrom(@event.Body.ToArray()) })
                            );
                    }

                    await Task.WhenAll(tasks);

                    rabbitMqProvider.Channel.BasicAck(@event.DeliveryTag, false);

                    logger.LogDebug("Handled event {eventName}", @event.RoutingKey);
                }
                catch (Exception e) {
                    logger.LogError(
                        "An unhandled exception occurred while processing {eventName}:\n{e}",
                        @event.RoutingKey,
                        e
                        );
                }
            };

            rabbitMqProvider.Channel.BasicConsume(queueName, false, consumer);
        }
Esempio n. 2
0
 public MessageQueuePublisher(RabbitMqProvider rabbitMqProvider, ILogger <RabbitMqProvider> logger)
 {
     this.rabbitMqProvider = rabbitMqProvider;
     this.logger           = logger;
 }