Singleton for service that takes a parameter

Viewed 130

In the DI container to create a singleton would the following be an ok way to do?

public void ConfigureServices(IServiceCollection services)
{
    var botClient = new TelegramBotClient(_config["Tokens:Telegram"]);
    services.AddSingleton(botClient);
}

TelegramBotClient is from the library that I'm using, so I can't start changing that.

1 Answers

A more orthadox way of handling a DI service with a configuration is to use the IOptions pattern. This way you aren't tightly coupling your startup object with the service. As it stands now, if your configuration changes, you have to modify your startup object.

A way to tackle this and keep your concerns separated, take a look at this:

TelegramBotClientService.cs

public interface ITelegramBotClientService
{
    Task DoSomethingAsync();
}

public sealed class TelegramBotClientService : ITelegramBotClientService
{
    private readonly TelegramConfigModel _config;

    public TelegramBotClientService(IOptions<TelegramConfigModel> options)
    {
        _config = options.Value;
    }

    public Task DoSomethingAsync()
    {
        var token = _config.Token;
        // ...
    }
}

Startup.cs

// ...
public void ConfigureServices(IServiceCollection services)
{
    services.Configure<TelegramConfigModel>(
            Configuration.GetSection("TelegramConfig"));

    services.AddSingleton<ITelegramBotClientService, TelegramBotClientService>();
}
// ...

appsettings.json

{
    "TelegramConfig": {
        "Token": "12345"
    }
}

TelegramConfigModel.cs

public sealed class TelegramConfigModel
{
    public string Token { get; set; }
}

This hasn't been tested, so there may be a typo somewhere, but, now your concerns are separated. The DI pipeline is now doing the instantiation and also injecting your configurations.

A side note

I noticed you may be injecting a singleton to maintain a bot. I would highly suggest you use IHostedService or BackgroundService and inject using AddHostedService to maintain something like a bot.

Related