Home > Blockchain >  C# Calling two classes that have the same interface
C# Calling two classes that have the same interface

Time:12-09

How can I call two methods that have the same interface? I've got a background service that read messages from a kafka queue by calling ConsumeMessagesFromQueue.

public class InboundWorker : BackgroundService
{
    private readonly IKafkaConsumer _kafkaConsumer;

    public InboundWorker(IKafkaConsumer kafkaConsumer)
    {
        _kafkaConsumer = kafkaConsumer;
    }

    protected override async Task ExecuteAsync(CancellationToken stoppingToken)
    {
        await _kafkaConsumer.ConsumeMessagesFromQueue(stoppingToken).ConfigureAwait(false);
    }
}

This is the interface:

public interface IKafkaConsumer
{
    Task ConsumeMessagesFromQueue(CancellationToken cancellationToken);
}

I've got a class with that interface:

public class KafkaConsumer : IKafkaConsumer
{
    private readonly AppSettings _appSettings;

    public KafkaConsumer(IOptions<AppSettings> appSettings)
    {
        _appSettings = appSettings;
    }

    public async Task ConsumeMessagesFromQueue(CancellationToken cancellationToken)
    {
        await Task.Delay(1);
    }
}

I want to be able to return and process data from another kafka queue as well. So I was thinking of creating another class that also implements the interface above IKafkaConsumer like so:

public class KafkaConsumerB : IKafkaConsumer
{
    private readonly AppSettings _appSettings;

    public KafkaConsumerB(IOptions<AppSettings> appSettings)
    {
        _appSettings = appSettings;
    }

    public async Task ConsumeMessagesFromQueue(CancellationToken cancellationToken)
    {
        await Task.Delay(1);
    }
}

With my ioc set up like so:

services.AddSingleton<IKafkaConsumer, KafkaConsumer>();
services.AddSingleton<IKafkaConsumer, KafkaConsumerB>();

However with the changes above mentioned, ConsumeMessagesFromQueue gets hit for KafkaConsumerB but not KafkaConsumer.

How can I get both methods to be hit? Rather than using the same interface (IKafkaConsumer) for KafkaConsumer and KafkaConsumerB, if I create another interface that's an exact duplicate of IKafkaConsumer but say IKafkaConsumerB for KafkaConsumerB, and register it, then both methods get called how I'd like. Since both interfaces are duplicate, I'm hoping to simplify things.

CodePudding user response:

If you want to use both implementations of the interfaces then you can inject them using an IEnumerable.

private readonly IEnumerable<IKafkaConsumer> _kafkaConsumer;

    public InboundWorker(IEnumerable<IKafkaConsumer> kafkaConsumer)
    {
        _kafkaConsumer = kafkaConsumer;
    }

Then call the methods using a foreach loop.

  • Related