Plain.HttpClientFactory
1.0.0
Requires NuGet 5.0 or higher.
dotnet add package Plain.HttpClientFactory --version 1.0.0
NuGet\Install-Package Plain.HttpClientFactory -Version 1.0.0
<PackageReference Include="Plain.HttpClientFactory" Version="1.0.0" />
<PackageVersion Include="Plain.HttpClientFactory" Version="1.0.0" />
<PackageReference Include="Plain.HttpClientFactory" />
paket add Plain.HttpClientFactory --version 1.0.0
#r "nuget: Plain.HttpClientFactory, 1.0.0"
#:package Plain.HttpClientFactory@1.0.0
#addin nuget:?package=Plain.HttpClientFactory&version=1.0.0
#tool nuget:?package=Plain.HttpClientFactory&version=1.0.0
Intuition
As we know http connection usage is quite complex in c#:
- If we create
HttpClienton each connection (HttpClientis not a sigleton) we have ports leakage - If
HttpClientis a sigleton, we din't react on DNS changes. It can be OK for command line utility, but not for ASP program. - We can use
IHttpClientFactory, but it is an overshoot for a simple routine when we want to connect and perform a single query.
This simple package is created to make http creation easier, especially when we want to create a library class which wants http connection:
public class MyLibraryClass {
private readonly m_ConnectionFactory;
// If we want to create library class instance within ASP we provide connection factory
public MyLibraryClass(IHttpConnectionFactory connectionFactory) {
m_ConnectionFactory = connectionFactory;
}
// If we want to create library class instance for a standalone routine which provides singleton connection
public MyLibraryClass(IHttpConnection connection) {
m_ConnectionFactory = IHttpClientFactory.FactoryFromClient(connection);
}
// If we want to create library class instance for a standalone routine which has no predefined connection
public MyLibraryClass() {
m_ConnectionFactory = IHttpClientFactory.DefaultFactory;
}
...
private async Task Perform() {
// Business as usual
using var http = m_ConnectionFactory.CreateClient();
...
}
}
Plain.HttpClientFactory
A lightweight and simple implementation of IHttpClientFactory for .NET that provides flexible HTTP client creation with shared handler management.
Overview
Plain.HttpClientFactory is a minimal NuGet package that offers alternative implementations of IHttpClientFactory for scenarios where you need simple, predictable HTTP client creation without the complexity of full dependency injection setup.
This package solves common HTTP client management challenges:
- ✅ Shared
SocketsHttpHandlerwith proper pooling and decompression - ✅ Connection lifetime management (100 seconds default)
- ✅ Support for wrapping existing
HttpClientinstances - ✅ Cookie and credential handling
- ✅ Fully unit tested with WireMock.Net
Features
1. DefaultHttpClientFactory
Creates HTTP clients with a shared SocketsHttpHandler that includes:
- Automatic decompression (gzip, deflate, brotli)
- Shared cookie container
- Default credentials support
- Configurable connection pooling (100 seconds lifetime)
var factory = new DefaultHttpClientFactory();
using var client = factory.CreateClient("myClient");
var response = await client.GetAsync("https://example.com");
2. ClientHttpClientFactory
Wraps an existing HttpClient instance and creates new clients that share its underlying handler. Useful for scenarios where you have a pre-configured client.
var originalClient = new HttpClient();
...
var factory = new ClientHttpClientFactory(originalClient);
using var newClient = factory.CreateClient("derived");
// Both clients share the same handler
3. Extension Methods
Convenient extension methods for working with IHttpClientFactory:
// Get the default factory
var factory = IHttpClientFactory.DefaultFactory;
// Create a factory from an existing client
var myClient = new HttpClient();
...
var factory = IHttpClientFactory.FactoryFromClient(myClient);
Installation
NuGet Package Manager:
Install-Package Plain.HttpClientFactory
.NET CLI:
dotnet add package Plain.HttpClientFactory
Or add directly to your .csproj:
<ItemGroup>
<PackageReference Include="Plain.HttpClientFactory" Version="*" />
</ItemGroup>
Requirements
- .NET 10.0 or higher
- Microsoft.Extensions.Http 10.0.12 or compatible
Architecture
Class Hierarchy
IHttpClientFactory (interface)
├── DefaultHttpClientFactory
│ └── Uses shared SocketsHttpHandler with automatic pooling
└── ClientHttpClientFactory
└── Wraps an existing HttpClient with ForwardingHandler
Key Components
- DefaultHttpClientFactory: Thread-safe singleton pattern with lazy-initialized handler
- ClientHttpClientFactory: Wraps existing clients using a custom
ForwardingHandler - ForwardingHandler: Internal message handler that forwards requests while managing request state
- HttpClientFactoryExtensions: Utility methods for factory creation and access
Configuration
DefaultHttpClientFactory Settings
The default factory uses these settings:
| Setting | Value | Purpose |
|---|---|---|
| Target Framework | .NET 10.0 | Latest .NET version support |
| Connection Lifetime | 100 seconds | Connection pooling timeout |
| Auto Decompression | All | gzip, deflate, brotli support |
| Credentials | Default | Uses system credentials |
| Cookie Container | Shared | Maintains cookies across requests |
Testing
The project includes comprehensive unit tests using xUnit and WireMock.Net:
dotnet test
Test Coverage
- ✅ Default HTTP client creation
- ✅ Shared handler verification
- ✅ Client wrapping functionality
- ✅ Extension method behavior
- ✅ Mock HTTP request/response handling
Differences from Microsoft.Extensions.Http
| Feature | Plain.HttpClientFactory | Microsoft.Extensions.Http |
|---|---|---|
| Setup | Minimal, no DI needed | Requires full DI setup |
| Handler Sharing | Automatic (Lazy<T>) | Manual or DI-based |
| Size | Lightweight | Full-featured |
| Scenarios | Simple to moderate | Complex enterprise |
| Learning Curve | Very low | Moderate |
Use Cases
✅ Best For:
- Small to medium applications
- Scenarios without dependency injection
- Quick prototyping
- Microservices with simple HTTP needs
- Legacy system integration
- Testing and mocking scenarios
API Reference
DefaultHttpClientFactory
public sealed class DefaultHttpClientFactory : IHttpClientFactory
{
public HttpClient CreateClient(string name);
public static TimeSpan ConnectionLifeTime { get; }
}
ClientHttpClientFactory
public sealed class ClientHttpClientFactory : IHttpClientFactory
{
public ClientHttpClientFactory(HttpClient originalClient);
public HttpClient CreateClient(string name);
}
Extension Methods
public static class HttpClientFactoryExtensions
{
public static IHttpClientFactory DefaultFactory { get; }
public static IHttpClientFactory FactoryFromClient(HttpClient? originalClient);
}
Contributing
Contributions are welcome! Please feel free to submit a Pull Request.
Development Setup
# Clone the repository
git clone https://github.com/Dmitry-Bychenko/Plain.HttpClientFactory.git
cd Plain.HttpClientFactory
# Restore dependencies
dotnet restore
# Run tests
dotnet test
# Build
dotnet build
# Pack NuGet
dotnet pack -c Release
License
This project is licensed under the MIT License.
Author
Dmitry Bychenko - GitHub Profile
Support
For issues, questions, or suggestions, please open an issue on GitHub.
Made with ❤️ for the .NET community
| Product | Versions Compatible and additional computed target framework versions. |
|---|---|
| .NET | net10.0 is compatible. net10.0-android was computed. net10.0-browser was computed. net10.0-ios was computed. net10.0-maccatalyst was computed. net10.0-macos was computed. net10.0-tvos was computed. net10.0-windows was computed. |
-
net10.0
- Microsoft.Extensions.Http (>= 10.0.12)
NuGet packages
This package is not used by any NuGet packages.
GitHub repositories
This package is not used by any popular GitHub repositories.
| Version | Downloads | Last Updated |
|---|---|---|
| 1.0.0 | 94 | 10/4/2026 |
Initial stable release
- DefaultHttpClientFactory implementation with shared SocketsHttpHandler
- ClientHttpClientFactory for wrapping existing HttpClient instances
- Extension methods for easy factory creation
- Full unit test coverage with WireMock.Net
- Comprehensive documentation and examples