Registering Services and HttpClient for Testable ASP.NET Core Apps
To make your ASP.NET Core services easy to test and maintain, follow this proven pattern. The example below demonstrates how to register a service and configure an HttpClient
with custom handlers, while keeping the design flexible for unit testing.
1. Register your service separately
Register your service interface and implementation as a singleton (or other lifetime as needed). This keeps the service replaceable in tests:
services.AddSingleton<IMyService, MyService>();
Tip: Use TryAdd for safe registration in reusable code
If your registration code is part of a shared library or package, use TryAdd
to avoid overriding existing registrations accidentally:
services.TryAddSingleton<IMyService, MyService>();
2. Configure an HttpClient with handlers
Use a named HttpClient to add retry and logging handlers. These handlers improve reliability and diagnostics:
services.AddHttpClient(nameof(MyService))
.AddHttpMessageHandler(s => new RetryHandler(s))
.AddHttpMessageHandler(s => new LoggingHandler(s));
3. Add memory caching safely
You can call AddMemoryCache()
without worry — it internally prevents duplicates:
services.AddMemoryCache();
Full Sample Method:
public static class ServiceCollectionExtensions
{
public static IServiceCollection AddMyClientServices(this IServiceCollection services)
{
ArgumentNullException.ThrowIfNull(services);
services.AddMemoryCache();
services.TryAddSingleton<IMyService, MyService>();
services.AddHttpClient(nameof(MyService))
.AddHttpMessageHandler(s => new RetryHandler(s))
.AddHttpMessageHandler(s => new LoggingHandler(s));
return services;
}
}
Why This Matters
- Separation of concerns makes your code easier to test.
- Named HttpClient with handlers improves reliability and debugging.
- TryAdd keeps your library safe and reusable.
- Memory cache registration is simple and safe.
Using this approach ensures your ASP.NET Core apps are easier to maintain, test, and extend.
Comments