在 DI 容器中创建单例,以下方法可行吗?
public void ConfigureServices(IServiceCollection services)
{
var botClient = new TelegramBotClient(_config["Tokens:Telegram"]);
services.AddSingleton(botClient);
}
TelegramBotClient 来 self 正在使用的库,因此我无法开始更改它。
最佳答案
通过配置处理 DI 服务的更正统方法是使用 IOptions
模式。这样,您就不会将启动对象与服务紧密耦合。就目前而言,如果您的配置发生变化,您就必须修改您的启动对象。
解决这个问题并区分您的担忧的方法,请看一下:
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; }
}
这尚未经过测试,因此某些地方可能存在拼写错误,但是,现在您的关注点已经分开了。 DI 管道现在正在进行实例化并注入(inject)您的配置。
A side note
我注意到您可能会注入(inject)一个单例来维护机器人。我强烈建议您使用 IHostedService
或 BackgroundService
并使用 AddHostedService
进行注入(inject)来维护类似机器人的东西。
关于c# - 带有参数的服务的单例,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/66017807/