Wiring the Keyright SDK into ASP.NET Core DI as a typed HttpClient with resilience
Most Keyright integrations start the same way: someone needs to validate a license against the self-hosted issuing service, so they write new HttpClient() , point it at the ServiceUrl , and ship it. It works in development and on the demo. Then it goes to production and one of two things happens. Either the client is created per call — a fresh HttpClient inside the method that checks the license…
Keyright integrations typically begin by validating a license against a self-hosted issuing service. To accomplish this, developers often begin by writing new HttpClient() instances, pointing them at the ServiceUrl, and integrating them directly into their code. This approach works well during development and even on demos. However, when deployed to production, two common issues emerge.
Either the client is created for each individual license check, resulting in excessive socket usage and potential timeouts due to TIME_WAIT connections, or a single static HttpClient is used throughout the process, which fixes socket issues but causes DNS resolution to be frozen indefinitely. In both cases, the root cause lies in manually managing the HttpMessageHandler.
The recommended solution within the ASP.NET Core framework involves registering the Keyright client as a typed client using IHttpClientFactory. This approach enables the factory to pool and rotate the underlying handler, thereby avoiding socket exhaustion and stale DNS issues. By injecting IKeyrightClient as any other service, the wrapper remains singleton-safe while ensuring the HttpClient is not held indefinitely.
After registering the client, it is advisable to attach AddStandardResilienceHandler() with timeout settings, retry mechanisms with jitter, and a circuit breaker tailored for licensing calls. This strategy allows for graceful degradation in the event of brief issues with the issuing service, preventing hard failures for paying customers.
The two primary anti-patterns to avoid when implementing this functionality are:
1. Creating a new HttpClient for each license validation check: Although this method disposes of each client, it leads to socket exhaustion over time, as each newly created client leaves connections in TIME_WAIT. As traffic increases, the ephemeral port range becomes saturated, causing SocketExceptions and hindering further requests.
2. Utilizing a single static HttpClient for the entirety of the process: While this approach prevents socket exhaustion by reusing connections, it freezes DNS resolution permanently. This problem becomes apparent when the issuing service's IP address changes or scales, causing the static client to continue attempting to connect to the old resolved address, which no longer exists.
Both methods demonstrate a partial understanding of HttpClient's resource consumption but neglect to address the critical aspect of handler rotation. The key takeaway from this solution is to register the Keyright client with AddHttpClient IKeyrightClient, KeyrightClient(), allowing the factory to manage the pool and rotation of the underlying handler. By doing so, developers can prevent socket exhaustion and stale DNS resolution while ensuring reliable and resilient communication with the Keyright issuing service.
Written by urgent.news from Dev.to's reporting — not their text. Machine-written — may contain errors; check the original before relying on it.