What is IHttpClientFactory and why should you use it?
Quick Answer
IHttpClientFactory manages the lifetime of HttpClient's underlying HttpMessageHandler, pooling and rotating them. It fixes two classic bugs: socket exhaustion (from new HttpClient() per call) and stale DNS (from one long-lived static HttpClient). It also gives you a clean place to add resilience (Polly) and default headers.
IHttpClientFactory exists because both obvious ways of using HttpClient are wrong. Newing one up per call leaks sockets and eventually exhausts the ports under load. Keeping one static instance forever means it never sees DNS changes. The factory pools the underlying message handlers and rotates them on a timer, and hands you a cheap HttpClient each time. I usually register a typed client — AddHttpClient<GitHubClient>() — so I inject GitHubClient and configure the base address and headers once, and I add a resilience handler for retries and a circuit breaker.
new HttpClient()per request leaves sockets inTIME_WAIT; under load you run out of ports.- A single static
HttpClientnever picks up DNS changes (failover, blue/green). - The factory pools handlers (default 2-minute lifetime) and hands you a lightweight
HttpClientwrapper each time — cheap to create, correct on lifetime. - Registration styles: named (
AddHttpClient("github", c => ...)), typed (AddHttpClient<GitHubClient>()— injectGitHubClientdirectly), or basic (AddHttpClient()then injectIHttpClientFactory). - Add
.AddPolicyHandler(...)/.AddStandardResilienceHandler()for retries, timeouts and circuit breakers.