I want to configure a HttpClient
to have a default authorization header that results from an async call like this:
builder.Services.AddHttpClient("client", (serviceProvider, client) =>
{
client.DefaultRequestHeaders.Authorization =
serviceProvider.GetService<IAuthProvider>()?.GetAuthHeaderAsync().Result;
});
Is it ok to call Task.Result
in configuration methods that do not support async delegates? or should I do this:
builder.Services.AddHttpClient("client", async (serviceProvider, client) =>
{
client.DefaultRequestHeaders.Authorization =
await serviceProvider.GetService<IAuthProvider>()?.GetAuthHeaderAsync();
});
- When I do this second option I'm getting a warning: Avoid using 'async' lambda when delegate type returns 'void'
CodePudding user response:
Dependency injection is one place where the "use async all the way" general advice isn't applicable, since no DI/IoC container supports asynchronous resolution.
One way to work around this is to use "asynchronous factory" types; i.e., you define an HttpClient
factory that can asynchronously produce a client on demand.
Another approach is to just do DI/IoC injection synchronously, usually blocking on all asynchronous construction at startup time, before the application has actually started.
A final approach is more advanced: you define a type that wraps all the APIs you need (with asynchronous signatures), and you hide the asynchronous initialization behind an async lazy (or a single-item async cache) within that type.
Regarding your specific use case, is the authentication header something that is only requested once, and remains constant for the rest of the app? If so, I would say to just synchronously block on it at startup. If it's something that can change, then you're probably better off handling authentication as a message handler, not at the point of constructing a client.