.netasp.net-web-apirabbitmq

How can I set up RabbitMQ in .NET Minimal Web API to then be able to use it in my services?


I want use AMQP connection string. I want to create a single shared connection (and channel per app lifetime to avoid resource exhaustion.


Solution

  • I found this way to do it:

        public class RabbitMqService
        {
            private readonly string _rabbitMqConnectionString;
            private IConnection? _connection;
            private IChannel? _channel;
            private readonly ILogger<RabbitMqService> _logger;
            private readonly IHttpContextAccessor _httpContextAccessor;
            private bool _initialized = false;
            public RabbitMqService(
                IConfiguration configuration,
                ILogger<RabbitMqService> logger,
                IHttpContextAccessor httpContextAccessor
            )
            {
                var rabbitMqSection = configuration.GetSection("RabbitMq");
                _rabbitMqConnectionString = rabbitMqSection["ConnectionString"]!;
                _logger = logger;
                _httpContextAccessor = httpContextAccessor;
            }
    
            private string GetCorrelationId()
            {
                return _httpContextAccessor.HttpContext?.TraceIdentifier 
                    ?? Guid.NewGuid().ToString();
            }
    
            public async Task InitAsync()
            {
                if (_initialized && _connection?.IsOpen == true && 
                    _channel?.IsOpen == true)
                    return;
                try
                {
                    var factory = new ConnectionFactory
                    {
                        Uri = new Uri(_rabbitMqConnectionString)
                    };
    
                    _connection = await factory.CreateConnectionAsync();
                    _channel = await _connection.CreateChannelAsync();
                    _initialized = true;
                }
                catch (Exception ex)
                {
                    _initialized = false;
                    string correlationId = GetCorrelationId();
                    _logger.LogError(ex, 
                        "Error in RabbitMq initAsync| CorrelationId: {CorrelationId}",
                        correlationId
                    );
                }
            }
    
            public async Task<IChannel> GetChannel()
            {
                if (_connection == null || 
                    !_connection.IsOpen || 
                    _channel == null || !_channel.IsOpen
                    )
                {
                    _initialized = false;
                    await InitAsync();
                }
    
                if (_channel == null)
                    throw new InvalidOperationException(
                    "Failed to initialize RabbitMQ channel."
                );
    
                return _channel;
            }
    
            public async ValueTask DisposeAsync()
            {
                if (_channel is not null)
                {
                    await _channel.CloseAsync();
                }
                if (_connection is not null)
                {
                    await _connection.DisposeAsync();
                }
            }
        } 
    
    
    And in the program.cs file:
    
    builder.Services.AddSingleton<RabbitMqService>();
    
    var app = builder.Build();
    
    using (var scope = app.Services.CreateScope())
    {
        var rabbitService = scope.ServiceProvider.GetRequiredService<RabbitMqService>();
        await rabbitService.InitAsync();
    }
    
    If there is a better way please share it and THANK you very much.