我已经阅读了很多关于HttpClient实例应该尽可能地重用,甚至在整个应用程序生命周期中都重用的文章。为了完整起见,以下是我基于以下几个资源发表我的观点:
- Do HttpClient and HttpClientHandler have to be disposed?
- You're Using HttpClient Wrong and it is Destabilizing Your Software
- What is the overhead of creating a new HttpClient per call in a WebAPI client?
我有几个问题:
- 如何在ASP.NET MVC中创建一个应用程序级别的HttpClient实例,以在所有请求之间共享?假设没有IoC容器,因此我不能只将其绑定到Singleton作用域并结束。我该如何手动完成?
- 此外,我正在与之交互的Web服务需要在每个请求上提供一个新的授权令牌,所以即使我想出了上述#1的方法,我如何在每个请求上提供新的授权标头,以便它不会与潜在的多个并发请求(来自不同的用户等)发生冲突?我了解到HttpClient本身在GetAsync和其他方法方面相当线程安全,但是设置DefaultAuthorizationHeaders对我来说似乎不是线程安全的,是吗?
- 如何保持它可单元测试?
这是我的正在进行中的代码(为了简洁起见,在此处略有简化):
public class MyHttpClientWrapper : IDisposable
{
private readonly HttpClient _httpClient;
private readonly TokenManager _tokenManager;
public HttpServiceClient(HttpClient httpClient, TokenManager tokenManager)
{
_httpClient = httpClient;
_tokenManager = tokenManager;
_httpClient.BaseAddress = new Uri("https://someapp/api/");
_httpClient.DefaultRequestHeaders.Accept.Add(new
MediaTypeWithQualityHeaderValue("application/json"));
}
public string GetDataByQuery(string query)
{
_httpClient.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue(
"amx", _tokenManager.GetNewAuthorizationCode());
var response = _httpClient.GetAsync(query).Result;
return response.Content.ReadAsStringAsync().Result;
}
public void Dispose()
{
HttpClient?.Dispose();
}
}
顺便提一下:我在这里使用了依赖注入,但不一定是一个IoC容器(由于与本讨论无关的原因)。