Register two jsonsetting in service collection in .net core

236 views Asked by At

I have two hosted services, which each service use its own rabbit mq address as you can see :

{
  "RabbitMQOptions": {
    "HostName": "172.23.131.1",
    "VirtualHost": "/",
    "Port": 5672,
    "Username": "**",
    "Password": "***!"
  },
  "RabbitMQOptions1": {
    "HostName": "172.23.39.1",
    "VirtualHost": "***",
    "Port": 5672,
    "Username": "***",
    "Password": "123456"
  }
}

I have two hosted service named N4 and Fund and each of them needs its own rabbitmq configuration Here is the code of my workers:

public class N2Worker : BackgroundService
{
    private readonly string QUEUE_CONSUMER_NAME;
    
    private readonly IRabbitMQConsumer _rabbitMQConsumer;
    
    public N2Worker(
        IRabbitMQConsumer rabbitMQConsumer,
        IConfiguration configuration)
    {
        _rabbitMQConsumer = rabbitMQConsumer;
    }
}

So in my program.cs I added this :

IHost host = Host.CreateDefaultBuilder(args)
    .ConfigureServices((hostContext, services) =>
    {
        services.AddRabbitMQ(hostContext.Configuration);
        services.AddHostedService<N2Worker>();
        services.AddHostedService<FundWorker>();
    })
    .Build();
    
await host.RunAsync();

So in AddRabbitMQ I have this:

public static IServiceCollection AddRabbitMQ(
    this IServiceCollection services, IConfiguration configuration)
{
    services.Configure<RabbitMQOptions>(configuration.GetSection(
        RabbitMQOptions.DefaultSectionName));
    services.AddSingleton<RabbitMqService>();
    
    return services;
}

And my rabbitService class is this:

public sealed class RabbitMqService
{
    private readonly RabbitMQOptions _configuration;

    public RabbitMqService(IOptions<RabbitMQOptions> options)
    {
        _configuration = options.Value;
    }

    public IConnection CreateConnection()
    {
        var connection = new ConnectionFactory()
        {
            HostName   =  _configuration.HostName,
            Port       = _configuration.Port,
            VirtualHost= _configuration.VirtualHost,
            UserName   =  _configuration.Username,
            Password   = _configuration.Password,
            DispatchConsumersAsync = true
        };
        
        return connection.CreateConnection();
    }
}

So as you can see in AppSetting I have different addresses, my question is how can I register two RabbitMQ instances with different configuration?

Here is the code of my consumer :

public sealed class RabbitMQConsumer : IRabbitMQConsumer, IDisposable
{
    private IModel _channel;
    private IConnection _connection;
    private readonly RabbitMqService _rabbitMqService;
    
    public RabbitMQConsumer(RabbitMqService rabbitMqService)
    {
        _rabbitMqService = rabbitMqService;
    }
}

I want to inject rabbitConsumer into each workes with different configuration I mean N4 uses RabbitMQOptions and fund uses RabbitMQOptions1

1

There are 1 answers

12
Steven On

You can't have two sections with the same name in your config name, so you'll have to name them differently, for instance:

  "RabbitMQOptions1": { ... },
  "RabbitMQOptions2": { ... }

Next, you'll have to register the two services seperately, while loading their individual configuration, for instance:

var options1 = Configuration.GetSection("RabbitMQOptions1").Get<RabbitMQOptions>();

services.AddSingleton<RabbitMqService>(_ => new RabbitMqService(options1));

var options2 = Configuration.GetSection("RabbitMQOptions2").Get<RabbitMQOptions>();

services.AddSingleton<RabbitMqService>(_ => new RabbitMqService(options2));

Last, as RabbitMqService now depends on RabbitMQOptions rather than IOptions<RabbitMQOptions>, you need to change its constructor:

public sealed class RabbitMqService
{
    private readonly RabbitMQOptions _configuration;

    public RabbitMqService(RabbitMQOptions options)
    {
        _configuration = options;
    }

    ...
}