Windows Forms app .Net Core 7.0 HttpClient Dependency Injection is null

509 Views Asked by At

I haven't found any sample of registering a HttpClient singleton in a Windows Forms app, and the way it's done in ASP.NET Core does not seem to work here. On Form constructor, dependency injected httpClient gives null value. How can I get a singleton instance of HttpClient on Form1 Dependency Injection?

My Program.cs.Main():

    [STAThread]
    static void Main()
    {
        ApplicationConfiguration.Initialize();

        var services = new ServiceCollection();
        services.AddHttpClient();
        services.AddScoped<Form1>();

        using (ServiceProvider serviceProvider = services.BuildServiceProvider())
        {
            var form1 = serviceProvider.GetRequiredService<Form1>();
            Application.Run(form1);
        }
    }

My Form1:

public partial class Form1 : Form
{

    [Inject] public HttpClient? http { get; set; }

    public Form1()
    {
        InitializeComponent();
        System.Diagnostics.Debug.WriteLine(http == null); // True
    }
}
1

There are 1 best solutions below

0
Matias Masso On

Finally got it working as follows:

  1. Declare a generic Host builder in Program.cs Main()
  2. Add IHttpClientFactory to the service Collection using the method AddHttpClient()
  3. Add main form Form1 as a transient service so HttpClient may be passed in its constructor
  4. Launch the Application passing the Form1 service as argument.
  5. In the Form constructor, store the http service argument in a local variable
  6. Call an async function to allow async calls
  7. Call CreateClient() method to instantiate the service
  8. Use it

Program.cs:

    [STAThread]
    static void Main()
    {
        var host = Host.CreateDefaultBuilder()
        .ConfigureServices((context, services) =>
        {
            services.AddHttpClient(); 
            services.AddTransient<Form1>();
        }).Build();

        Application.Run(host.Services.GetRequiredService<Form1>());
    }

Form1:

public partial class Form1 : Form
{
    private IHttpClientFactory _httpClientFactory;

    public Form1(IHttpClientFactory _httpClientFactory)
    {
        InitializeComponent();
        this._httpClientFactory = _httpClientFactory;
        base.Load += async (s, e) => { await LoadAsync(this, new EventArgs()); };
    }

    private async Task LoadAsync(object sender, EventArgs e)
    {
        var client = _httpClientFactory.CreateClient();
        client.BaseAddress = new Uri("https://api.publicapis.org/");
        var url = string.Format("entries");
        var result = await client.GetAsync(url);
        MessageBox.Show(((int)result.StatusCode).ToString());
    }
}