We are building .NET Core microservices.
Many of our microservices use HttpClient
logging through ConfigurePrimaryMessageHandler()
With .NET Core 2+ our approach had been to
services.AddHttpClient().ConfigurePrimarymessageHandler()
in ConfigureServices
of Startup.cs
. We had to pass in a ILogger<T>
here and we would get that by injecting it into our Startup constructor.
Now that we have migrated to IHostEnvironment
we can no longer use DI to inject ILogger<T>
into Startup constructor AND we can't inject IServiceCollection
into Configure()
.
One idea I had was to create the HttpClientBuilder
, store a reference to it and then do the ConfigurePrimaryMessageHandler
in Configure
... This did NOT work. I'm assuming because once it is built, it is built so you need to do it in ConfigureServices
.
So I ended up coming up with a nasty hack that works but it feels yucky:
I have an ILogger<T>
as a protected member of my Startup.cs
.
I pass that in (its null) into my HttpClientBuilder
s...
Then in Configure()
I inject ILogger<T>
and set the protected member variable.
Yuck!
It kind of looks like this:
class Startup
{
protected ILogger<HttpClientLoggingHandler> _logHack;
public void ConfigureServices(IServiceCollection)
{
services.AddHttpClient<T>().ConfigurePrimaryMessageHandler(()=>{ new
HttpClientLoggingHandler(_logHack, otherstuff) });
}
public void Configure(IApplicationBuilder bld, ILogger<T> logForHack, otherstufffordi)
{
_logHack = logForHack; // note this works, but is this really a good design pattern?
}
}
So this does work... But it doesn't feel like a really great design pattern. Any advice out there anyone? Is this really the approach we should be taking? Feel like something was missed here when we migrated to IHostEnvironment
.
You can simply do .ConfigurePrimaryMessageHandler<HttpClientLoggingHandler>();
, provided the HttpClientLoggingHandler
is registered.
The lambda overloads for ConfigurePrimaryMessageHandler
also can pass you an IServiceProvider
. From there, call sp.GetRequiredService<T>
.