关于如何在 .NET 5.0 Worker Service 中最好地使用 DI 注册 EventGridClient 的指南

问题描述

我正在使用 Microsoft.Azure.EventGrid NuGet 包中的 EventGridClient 将事件发布到 Azure 事件网格主题。我知道工作服务是用单例生命周期注册的。我正在寻找有关如何最好地将 EventGridClient 注册到工作服务中的 DI 容器的指南?我正在使用 Windows 服务中托管的 .NET 5.0 工作器。

DI 注册(不确定我在这里是否做对了):

Host.CreateDefaultBuilder(args)
.UseWindowsService()
.ConfigureServices((hostContext,services) =>
{
    services.AddSingleton(new EventGridClient(new TopicCredentials("topicKey"),// proxy auth
        new HttpClientHandler {DefaultProxyCredentials = CredentialCache.DefaultCredentials}));
    services.AddHostedService<Worker>();

})
.Build()
.Run();

Worker 实现:

public class Worker : BackgroundService
{
    private readonly EventGridClient client;
    private readonly ILogger<Worker> logger;

    public Worker(EventGridClient client,ILogger<Worker> logger)
    {
        this.client = client;
        this.logger = logger;
    }

    protected override async Task ExecuteAsync(CancellationToken stoppingToken)
    {
        while (!stoppingToken.IsCancellationRequested)
        {
            var events = new List<EventGridEvent>();

            await client.PublishEventsAsync("topicHostname",events,stoppingToken);

            logger.LogInformation("Worker running at: {time}",DateTimeOffset.Now);
            await Task.Delay(1000,stoppingToken);
        }
    }
}

非常感谢任何指导。

解决方法

我在他们的问答网站上收到了 Microsoft 的回答,我将其粘贴在这里以防其他人面临同样的问题。

虽然您的 DI 注册在技术上是好的,是的,它应该是单例的,因为它涉及 http 连接 (refer Improper Instantiation antipattern for details),您可以通过针对 {{1 注册接口 IEventGridClient 使其更好和可测试}} 并改为注入 IEventGridClient。

EventGridClient

...

//...
.ConfigureServices((hostContext,services) =>
 {
     services.AddSingleton<IEventGridClient>(new EventGridClient(new TopicCredentials("topicKey"),// proxy auth
         new HttpClientHandler {DefaultProxyCredentials = CredentialCache.DefaultCredentials}));
     services.AddHostedService<Worker>();
    
 })

但请注意,由于 PublishEventsAsync 是 IEventGridClient,如果您为代码编写单元测试并注入 模拟 IEventGridClient,记得模拟设置方法 private readonly IEventGridClient client; private readonly ILogger<Worker> logger; public Worker(IEventGridClient client,ILogger<Worker> logger) { this.client = client; this.logger = logger; } 的 IEventGridClient 使您的测试 不会真正调用事件网格。

相关问答

错误1:Request method ‘DELETE‘ not supported 错误还原:...
错误1:启动docker镜像时报错:Error response from daemon:...
错误1:private field ‘xxx‘ is never assigned 按Alt...
报错如下,通过源不能下载,最后警告pip需升级版本 Requirem...