简体   繁体   中英

Guidance on how to best register the EventGridClient with DI in a .NET 5.0 Worker Service

I'm using the EventGridClient from the Microsoft.Azure.EventGrid NuGet package to publish events to an Azure Event Grid Topic. I understand that worker services are registered with singleton lifetime. I'm looking for guidance on how to best register the EventGridClient with the DI container in a worker service? I'm using a .NET 5.0 worker hosted in a windows services.

DI registration (not sure if I've done the right thing here):

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 implementation:

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);
        }
    }
}

Any guidance is highly appreciated.

I received an answer from Microsoft on their Q & A site which i'm pasting here in case someone else faces the same question.

While your DI registration is technically fine and yes, it should be singleton as it involves http connection ( refer Improper Instantiation antipattern for details ), you can make it nicer and testable by registering the interface IEventGridClient against EventGridClient and inject IEventGridClient instead.

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

...

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

But note that since PublishEventsAsync is an extension method of IEventGridClient, if you write unit test for your code and inject a mock of IEventGridClient, remember to mock setup the method PublishEventsWithHttpMessages of IEventGridClient so that your test does not make a real call to event grid.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM