reuben42
reuben42

Reputation: 45

HttpClientFactory singleton across application in a console app no Hosting

I am attempting to create a singleton for an httpclientfactory in a .Net 8 console application without using the Hosting extension. I was able to get something to work, but I'm not sure that it is thread-safe as well as an actual singleton throughout the application.

One piece I am missing is how a singleton works across classes. Does DI handle that itself?

Looking at Microsoft's example at text, but was unable to apply it to my needs.

Also, note that several requests have a default request header cookie, but not all of them.

Will this work as an actual thread-safe singleton of httpclientfactory or does this create multiple instances of it?

Program.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);

Other class:

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;
        }

    }
}

Upvotes: 0

Views: 320

Answers (1)

FireAlkazar
FireAlkazar

Reputation: 1880

One piece I am missing is how a singleton works across classes. Does DI handle that itself?

Yes.

Will this work as an actual thread-safe singleton of httpclientfactory or does this create multiple instances of it?

DefaulHttpClientFactory is thread-safe and registered as singleton.

Also, note that several requests have a default request header cookie, but not all of them.

You can use named or typed clients to handle that in a clean and correct way.

Upvotes: 0

Related Questions