.netdependency-injectionwebformshttpclientfactory

IHttpClientFactory in .NET Framework 4.7.2 without Dependency Injection


I am planning to use Microsoft.Extensions.Http package in my ASP.NET Framework 4.7.2 Webforms project. Since there is no built-in DI Container in .NET Framework, I am not using the DI packages. Based on this answer, I am not sure about the last line -

Microsoft.Extensions.Http provides the HttpClientFactory only, not the new optimized HttpClient. This is only available in .NET Core 2.1

Can I implement IHttpClientFactory without DI and using singleton method in my Framework project and get rid of the 2 problems of using HttpClient directly - Socket Exhaustion and DNS resolution? Is there something else that needs to be done based on the above comment


Solution

  • Unfortunately, the use of the HttpClientFactory is tightly integrated with the DI framework. Fortunately, creating a new IHttpClientFactory without making use of the full DI infrastructure can be done in a few lines:

    IHttpClientFactory factory = new ServiceCollection()
        .AddHttpClient()
        .BuildServiceProvider()
        .GetRequiredService<IHttpClientFactory>();
    

    With the code above you create new new service provider (which is the MS.DI Container) that just contains the registrations for the HTTP client package, which includes a registration for IHttpClientFactory, and the IHttpClientFactory is directly pulled from the container. The factory is stored in a variable, while the container itself is no longer used.

    A full working Console application would like like this:

    // This requires the 'Microsoft.Extensions.Http` package to be installed
    using Microsoft.Extensions.DependencyInjection;
    using System;
    using System.Net.Http;
    using System.Text.RegularExpressions;
    using System.Threading.Tasks;
    using System.Web;
    
    internal class Program
    {
        static async Task Main(string[] args)
        {
            IHttpClientFactory factory = new ServiceCollection()
                .AddHttpClient()
                .BuildServiceProvider()
                .GetRequiredService<IHttpClientFactory>();
    
            HttpClient client = factory.CreateClient();
    
            string html = await client.GetStringAsync(
                "https://blogs.cuttingedge.it/steven/posts/2011/" +
                "meanwhile-on-the-command-side-of-my-architecture/");
    
            string plainText = HttpUtility.HtmlDecode(
                Regex.Replace(
                    Regex.Replace(html, "<[^>]*>", string.Empty),
                    @"^\s*$\n", string.Empty, RegexOptions.Multiline));
    
            Console.WriteLine(plainText);
    
            Console.ReadLine();
        }
    }
    

    Best is to cache the IHttpClientFactory for the lifetime of your application and not recreate it on the fly.