c# - 带有参数的服务的单例

标签 c# asp.net-core

在 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)一个单例来维护机器人。我强烈建议您使用 IHostedServiceBackgroundService 并使用 AddHostedService 进行注入(inject)来维护类似机器人的东西。

关于c# - 带有参数的服务的单例,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/66017807/

相关文章:

c# - Google Drive API/SDK,使用服务帐户更改所有者失败

c# - 捕获 HttpRequestValidationException 并将其添加到 ModelState 的最佳方法是什么?

c# - 如何在 C# 中获取完整的主机名?

active-directory - .net5 MVC6 应用程序上的 Active Directory/LDAP

azure - 如何获取 Azure AD 经过身份验证的用户的用户名和电子邮件

c# - 我可以在一个环境中使用不同的配置运行两个 TestServers 吗?

c# - 从非托管 C++ 配置 .NET 库

C#如何解析XML文件

c# - 如何为 UseStaticFiles 引入更多扩展

c# - IAsyncActionFilter 返回空白页