Ejemplo n.º 1
0
        public async Task PublishAsync <T>(T @event) where T : IntegrativeEvent
        {
            var channel  = _channelPool.Get();
            var exchange = typeof(T).GetEventExchange();

            try
            {
                channel.BasicPublish(
                    exchange: exchange,
                    routingKey: "",
                    basicProperties: null,
                    body: @event.Serialize());

                _logger.LogTrace("Event {Id} published on {Exchange}",
                                 @event.Id,
                                 exchange);

                await _storage.SaveAsync(@event, OperationType.Send, OperationStatus.Succeeded);
            }
            catch
            {
                _logger.LogError("Faild to publish event {Id} on {Exchange}",
                                 @event.Id,
                                 exchange);

                await _storage.SaveAsync(@event, OperationType.Send, OperationStatus.Failed);
            }

            _channelPool.Release(channel);
        }
        protected override Task ExecuteAsync(CancellationToken stoppingToken)
        {
            foreach (var module in _modules)
            {
                var queue = module.Command.GetCommandQueue();

                try
                {
                    var channel = _connection.CreateModel();
                    channel.QueueDeclare(
                        queue: queue,
                        durable: true,
                        exclusive: false,
                        autoDelete: false);

                    _logger.LogInformation("Successfully connected to {Queue}", queue);

                    var consumer = new EventingBasicConsumer(channel);
                    consumer.Received += (model, ea) =>
                    {
                        var command = (dynamic)ea.Body.Deserialize(module.Command);

                        _logger.LogTrace("Command {Id} received from {Queue}", (Guid)command.Id, queue);

                        try
                        {
                            using (var scope = _scopeFactory.CreateScope())
                            {
                                var     type        = typeof(ICommandHandler <>);
                                var     typeArgs    = new Type[] { command.GetType() };
                                var     serviceType = type.MakeGenericType(typeArgs);
                                dynamic service     = scope.ServiceProvider.GetService(serviceType);
                                service.HandleAsync(command).Wait();
                            }

                            channel.BasicAck(deliveryTag: ea.DeliveryTag, multiple: false);

                            _logger.LogTrace("Command {Id} handled", (Guid)command.Id);
                            _storage.SaveAsync(command, OperationType.Receive, OperationStatus.Succeeded).Wait();
                        }
                        catch (Exception exp)
                        {
                            _logger.LogError(exp, "An exception was thrown while handling command {CommandId}", (Guid)command.Id);
                            _storage.SaveAsync(command, OperationType.Receive, OperationStatus.Failed).Wait();
                        }
                    };

                    channel.BasicConsume(
                        queue: queue,
                        autoAck: false,
                        consumer: consumer);
                }
                catch (Exception exp)
                {
                    _logger.LogCritical(exp, "Faild to connect to {Queue}", queue);
                }
            }

            return(Task.CompletedTask);
        }
        protected override Task ExecuteAsync(CancellationToken stoppingToken)
        {
            foreach (var module in _modules)
            {
                var exchange = module.Event.GetEventExchange();

                try
                {
                    var channel = _connection.CreateModel();
                    channel.ExchangeDeclare(
                        exchange: exchange,
                        type: ExchangeType.Fanout);

                    var queue = channel.QueueDeclare().QueueName;
                    channel.QueueBind(
                        queue: queue,
                        exchange: exchange,
                        routingKey: "");

                    _logger.LogInformation("Successfully connected to {Exchange}", exchange);

                    var consumer = new EventingBasicConsumer(channel);
                    consumer.Received += (model, ea) =>
                    {
                        var @event = (dynamic)ea.Body.Deserialize(module.Event);

                        _logger.LogTrace("Event {Id} received from {Exchange}", (Guid)@event.Id, exchange);

                        try
                        {
                            using (var scope = _scopeFactory.CreateScope())
                            {
                                var service = (dynamic)ActivatorUtilities.CreateInstance(
                                    scope.ServiceProvider,
                                    module.Handler);

                                service.HandleAsync(@event).Wait();
                            }

                            channel.BasicAck(ea.DeliveryTag, false);

                            _logger.LogTrace("Event {Id} handled", (Guid)@event.Id);
                            _storage.SaveAsync(@event, OperationType.Receive, OperationStatus.Succeeded).Wait();
                        }
                        catch (Exception exp)
                        {
                            _logger.LogError(exp, "An exception was thrown while handling event {EventId}", (Guid)@event.Id);
                            _storage.SaveAsync(@event, OperationType.Receive, OperationStatus.Failed).Wait();
                        }
                    };

                    channel.BasicConsume(
                        queue: queue,
                        autoAck: false,
                        consumer: consumer);
                }
                catch (Exception exp)
                {
                    _logger.LogCritical(exp, "Faild to connect to {Exchange}", exchange);
                }
            }

            return(Task.CompletedTask);
        }