Я пытаюсь создать синглтон для httpclientfactory в консольном приложении .Net 8 без использования расширения хостинга. Мне удалось заставить что-то работать, но я не уверен, что это является потокобезопасным, а также фактическим синглтоном во всем приложении.
Одна вещь, которую мне не хватает, — это то, как синглтон работает в разных классах. DI справляется с этим сам?
Посмотрел пример Microsoft в тексте, но не смог применить его к своим потребностям.
Также обратите внимание, что некоторые запросы имеют файл cookie заголовка запроса по умолчанию, но не все из них.
Будет ли это работать как настоящий поточно-ориентированный синглтон httpclientfactory или будет создано несколько его экземпляров?
Программа.cs:
using HttpClientFactoryConsole;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
IHttpClientFactory factory = new ServiceCollection()
.AddHttpClient()
.BuildServiceProvider()
.GetRequiredService\<IHttpClientFactory\>();
HttpClient hclient = factory.CreateClient();
//use hclient to get authorization cookie
string endpoint = "https://www.microsoft.com/login";
//string response = "";
HttpResponseMessage response = new HttpResponseMessage();
string cookie;
JObject joauth = new JObject()
{
{"userName","user"},
{"password","password"}
};
HttpContent content = new StringContent(joauth.ToString());
content.Headers.ContentType = new System.Net.Http.Headers.MediaTypeHeaderValue("application/json");
try
{
//HttpClient hclient = new HttpClient();
//httpContent.Headers.ContentType = new System.Net.Http.Headers.MediaTypeHeaderValue("application/json");
response = await hclient.PostAsync(endpoint, content);
}
catch (Exception ex)
{
Console.WriteLine(ex);
}
cookie = response.Headers.GetValues("Set-Cookie").First();
OtherClass ot = new OtherClass(factory);
JObject setup = await ot.PermitSetupAsync(cookie);
Другой класс:
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
namespace HttpClientFactoryConsole
{
internal class OtherClass
{
private readonly IHttpClientFactory _httpClientFactory;
public OtherClass(IHttpClientFactory httpClientFactory) => _httpClientFactory = httpClientFactory;
public async Task<JObject> PermitSetupAsync(string authcookie)
{
HttpClient hclient = _httpClientFactory.CreateClient();
JObject jSetup = new JObject();
string setupstring = "";
Stream setupstream;
string endpoint = "http://www.microsoft.com/setup";
//string response = "";
HttpResponseMessage response = new HttpResponseMessage();
try
{
hclient.DefaultRequestHeaders.Add("Cookie", authcookie); //first add of default header?
//httpContent.Headers.ContentType = new System.Net.Http.Headers.MediaTypeHeaderValue("application/json");
response = await hclient.GetAsync(endpoint);
setupstream = await response.Content.ReadAsStreamAsync();
using (var streamReader = new StreamReader(setupstream))
{
setupstring = streamReader.ReadToEnd();
jSetup = (JObject)JsonConvert.DeserializeObject(setupstring);
}
}
catch (Exception ex)
{
Console.WriteLine(ex);
}
return jSetup;
}
}
}





Одна вещь, которую мне не хватает, — это то, как синглтон работает в разных классах. Делает Я справлюсь с этим сам?
Да.
Будет ли это работать как настоящий поточно-ориентированный синглтон httpclientfactory? или это создает несколько его экземпляров?
DefaulHttpClientFactory является потокобезопасным и зарегистрирован как синглтон.
Также обратите внимание, что некоторые запросы имеют файл cookie заголовка запроса по умолчанию. Но не все из них.
Вы можете использовать именованные или типизированные клиенты, чтобы справиться с этим чистым и правильным способом.