I have a Windows Service written in .NET 8 that uses C# classes, some of which use Dependency Injection (the AddSendGrid() extension) to get an instance of ISendGridClient. It seems that when using this in a Windows service, or otherwise a C# class that's loaded once and remains active for the entire application's runtime (basically think of it being used in a Singleton), our application logs are flooded with messages like this (note InjectableSendGridClient:
As you can see, after the given class is alive for 2 minutes, the cleanup cycle runs every 10 seconds after the fact. It appears that ISendGridClient is keeping a single HttpClient instance alive for the entire duration the ISendGridClient remains in scope.
Is there a way to use ISendGridClient in a disposable context? Something like using(ISendGridClient client = someFactory.CreateClient())? Or, would it be possible that, when injecting ISendGridClient via dependency injection (i.e. constructor injection) for it to manage its internal client so it isn't "kept alive" for long-running services/processes? Some way to support using ISendGridClient in singleton/long-running scenarios?
Note that I cannot simply "turn off logging at the Debug level" in this scenario.
Here's how we're setting up dependency injection in Program.cs:
using Microsoft.Extensions.Hosting;
using SendGrid.Extensions.DependencyInjection;
HostApplicationBuilder builder = Host.CreateApplicationBuilder();
builder.Services.AddSendGrid(opts => opts.ApiKey = "my-api-key");
Here's how we're using the class:
using SendGrid;
public class SendGridEmailService(ILogger<SendGridEmailService> logger, ISendGridClient client)
{
// ISendGridClient used in this class
}
Current Workaround
Presently my only idea is to inject IServiceProvider instead, then get the client at runtime.
public class SendGridEmailSErvice(ILogger<SendGridEmailService> logger, ISerivceProvider provider)
{
public async Task SendMailAsync(SendGridMessage message, CancellationToken cancellationToken)
{
ISendGridClient sendGridClient = provider.GetRequiredService<ISendGridClient>();
await sendGridClient.SendEmailAsync(message, cancellationToken);
}
}
I have a Windows Service written in .NET 8 that uses C# classes, some of which use Dependency Injection (the
AddSendGrid()
extension) to get an instance ofISendGridClient
. It seems that when using this in a Windows service, or otherwise a C# class that's loaded once and remains active for the entire application's runtime (basically think of it being used in a Singleton), our application logs are flooded with messages like this (noteInjectableSendGridClient
:As you can see, after the given class is alive for 2 minutes, the cleanup cycle runs every 10 seconds after the fact. It appears that
ISendGridClient
is keeping a singleHttpClient
instance alive for the entire duration theISendGridClient
remains in scope.Is there a way to use
ISendGridClient
in a disposable context? Something likeusing(ISendGridClient client = someFactory.CreateClient())
? Or, would it be possible that, when injectingISendGridClient
via dependency injection (i.e. constructor injection) for it to manage its internal client so it isn't "kept alive" for long-running services/processes? Some way to support usingISendGridClient
in singleton/long-running scenarios?Note that I cannot simply "turn off logging at the Debug level" in this scenario.
Here's how we're setting up dependency injection in
Program.cs
:Here's how we're using the class:
Current Workaround
Presently my only idea is to inject
IServiceProvider
instead, then get the client at runtime.