Я хорошо прочитал, как экземпляры HttpClient следует использовать как можно больше, возможно даже на протяжении всего жизненного цикла приложения. Для полноты, вот несколько ресурсов, которые я основывая свои утверждения на:Повторное использование 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?
У меня есть несколько вопросов относительно этого:
- Как создать экземпляр приложения HttpClient с областью приложения в ASP.NET MVC для совместного использования среди всех запросов? Предположим, что на картинке нет контейнера IoC, поэтому я не могу просто привязать его в области Singleton с помощью container-name-here и называть его днем. Как мне это сделать? вручную? "
- Кроме того, веб-сервис я взаимодействующий с требует нового маркера авторизации на каждый запрос, так что даже если придумать способом сделать # 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();
}
}
Side Примечание: Я использую инъекции зависимостей здесь, но не обязательно IoC (по причинам, не имеющим отношения к этому обсуждению).
Предполагая, что ваше приложение асинхронно, что произойдет, если несколько потоков войдут в GetDataByQuery, и все они меняют DefaultRequestHeaders.Авторизация? Я считаю, что вы можете создать объект HttpRequestMessage, установить на нем заголовок авторизации и, наконец, вызвать _httpClient.SendAsync (requestMessage) – raRaRa
Да, хорошая точка. В какой-то момент я понял одно и то же, и начал делать то, что вы там описали. – Jiveman