问题描述
我正在使用 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 使您的测试
不会真正调用事件网格。