AugusteVN.HttpClient
1.1.4
dotnet add package AugusteVN.HttpClient --version 1.1.4
NuGet\Install-Package AugusteVN.HttpClient -Version 1.1.4
<PackageReference Include="AugusteVN.HttpClient" Version="1.1.4" />
<PackageVersion Include="AugusteVN.HttpClient" Version="1.1.4" />
<PackageReference Include="AugusteVN.HttpClient" />
paket add AugusteVN.HttpClient --version 1.1.4
#r "nuget: AugusteVN.HttpClient, 1.1.4"
#:package AugusteVN.HttpClient@1.1.4
#addin nuget:?package=AugusteVN.HttpClient&version=1.1.4
#tool nuget:?package=AugusteVN.HttpClient&version=1.1.4
HttpClient Wrapper & Resolver
- DEPRECATED -
Not following the best practices so I will deprecate this one soon, find a better way: AugusteVN.HttpClient.Delegator
Learn more: Delegating Handler
About
Register your distinctly-configured HttpClient
instance once to access it anywhere!
To see it in action and which problem it solves:
What's inside?
The HttBaseClient
serves as a wrapper class holding a configured HttpClient
instance.
A HttpClientResolver
can resolve that exact HttpClient
instance anywhere in your application.
Even in a (higher-level) referenced project (e.g. a standalone module) without polluting it with details of the implementation project.
What does it do?
This allows any caller to mutate the HttpClient
instance's properties which any other caller can then instantly use.
Think of it as a globally shared HttpClient
instance.
A drawback could be that setting 'breaking' property values would break one or more callers' HTTP capabilities.
But this package also allows to register multiple distinctly-configured HttpClient
instances that can work alongside each other.
For example, class A and component B inject HttpClient
instance X, class A sets instance X's authorization header value with a bearer token.
Component B can now automatically also make authorized HTTP calls due to that authorization header being set.
The above is not easy to accomplish with the out-of-the-box 'named' or 'typed' HttpClient
instances since those result in a new client instance for each caller.
Those only share the initially configured properties, like the BaseAddress
.
For example, authorizing one caller's HttpClient
instance after initialization will only authorize that caller's HttpClient
instance.
This means that you would have to manually authorize each caller's HttpClient
instance individually.
If selectively mutating individual HttpClient
instances is what you need, than stick with the default, named or typed approaches.
What is it for?
This package is most useful for project setups that require multiple, distinctly-configured HttpClient
instances to work alongside each other.
For example, a Blazor application that implements multiple Razor class libraries which are each responsible for communicating with a different API.
These multiple HttpClient
instances coming together in the Blazor app mustn't interfere with one another.
And, this packages makes it should be easy to authorize all HTTP calls for a distinctly-configured HttpClient
instance.
If your application only needs to communicate with one API, just use the default HttpClient
.
If your application does not need to mutate properties and easily share those mutations with other callers, use the default, named or typed HttpClient
instances.
Usage
Register once, access anywhere
Registering one new keyed, scoped HttBaseClient
holding a distinctly-configured HttpClient
instance with its BaseAddress
set.
Also registers a HttpClientResolver<T>
with interface IHttpClient<T>
which can be used to access / resolve that keyed HttpBaseClient
.
Program.cs
public record TExample;
// Just once, can be accessed in all callers.
builder.Services.AddKeyedHttpClientScoped<TExample>(clientName: nameof(TExample), baseAddress: "https://localhost:3000");
builder.Services.AddScoped<CallingService1>();
builder.Services.AddScoped<CallingService5>();
app.MapGet("/", (CallingService1 s1, CallingService5 s5) => {
s1.AuthorizeHttpClient("<token>");
s5.PrintAuthValue(); // Print: <token>
});
CallingService1.cs
public class CallingService1 {
private readonly HttpClient _httpClient;
public CallingService1(IHttpClient<TExample> httpBaseClient) {
_httpClient = httpBaseClient.GetClient();
}
public void AuthorizeHttpClient(string? token) {
_httpClient.DefaultHeaders.Authorization = new AuthenticationHeaderValue("Bearer", token);
}
}
CallingService5.cs
public class CallingService5 {
private readonly HttpClient _httpClient;
public CallingService5(IHttpClient<TExample> httpBaseClient) {
_httpClient = httpBaseClient.GetClient();
}
public void PrintAuthValue() {
Console.WriteLine("Print: " + _httpClient.DefaultHeaders.Authorization);
}
}
It is possible to mutate the HttpClient
instance, like setting a bearer token in one caller to than also be able to access that value in another caller.
So, the callers are sharing / using the same HttpClient
instance.
The above approach is recommended when you have multiple callers that need to access that shared HttpClient
instance.
Resolve elsewhere
After keyed registration, you can easily access / resolve this HttpBaseClient
by injecting IHttpClient<T>
or injecting the resolver directly HttpClientResolver<T>
.
This injection is possible in any caller class or (Razor) component.
After keyed registration, to access that same distinctly-configured HttpClient
instance e.g. in a higher-level standalone (module) class library, register only the resolver AddHttpClientResolverScoped<T>
.
After which you can resolve it, injecting the IHttpClient<T>
or HttpClientResolver<T>
.
Program.cs or Extensions.cs or ConfigureServices.cs or ...
builder.Services.AddHttpClientResolverScoped<ModuleService>("TExample");
builder.Services.AddScoped<ModuleService>();
app.MapGet("/", (ModuleService m) => {
m.PrintAuthValue(); // Print: <token>
});
ModuleService.cs
public class ModuleService {
private readonly HttpClient _httpClient;
public ModuleService(IHttpClient<ModuleService> httpBaseClient) {
_httpClient = httpBaseClient.GetClient();
}
public void PrintAuthValue() {
Console.WriteLine("Print: " + _httpClient.DefaultHeaders.Authorization);
}
}
Register multiple, access targeted
You can register and use multiple HttpBaseClient
instances alongside each other with each holding their own distinctly-configured HttpClient
instance.
All callers can now easily choose which API to communicate with by resolving its distinctly-configured HttpBaseClient
.
This also registers the callers as scoped.
Program.cs
builder.Services.AddKeyedHttpClientScoped<ApiService1>(clientName: "api-1", baseAddress: "https://api-url-1");
builder.Services.AddKeyedHttpClientScoped<IApiService2, ApiService2>(clientName: "api-2", baseAddress: "https://api-url-2");
app.MapGet("/", (ApiService1 a1, ApiService2 a2) =>
{
a1.PrintBaseAddress(); // ApiService1: https://api-url-1
a2.PrintBaseAddress(); // ApiService2: https://api-url-2
Results.Ok();
});
ApiService1.cs
public class ApiService1
{
private readonly HttpClient _httpClient;
public ApiService1(IHttpClient<ApiService1> httpClient)
{
_httpClient = httpClient.GetClient();
}
public void PrintBaseAddress()
{
Console.WriteLine("ApiService1: " + _httpClient.BaseAddress);
}
}
ApiService2.cs
public class ApiService2
{
private readonly HttpClient _httpClient;
public ApiService2(IHttpClient<ApiService2> httpClient)
{
_httpClient = httpClient.GetClient();
}
public void PrintBaseAddress()
{
Console.WriteLine("ApiService2: " + _httpClient.BaseAddress);
}
}
Brought to you by: kiss-code.com.
Product | Versions Compatible and additional computed target framework versions. |
---|---|
.NET | net8.0 is compatible. net8.0-android was computed. net8.0-browser was computed. net8.0-ios was computed. net8.0-maccatalyst was computed. net8.0-macos was computed. net8.0-tvos was computed. net8.0-windows was computed. net9.0 was computed. net9.0-android was computed. net9.0-browser was computed. net9.0-ios was computed. net9.0-maccatalyst was computed. net9.0-macos was computed. net9.0-tvos was computed. net9.0-windows was computed. net10.0 was computed. 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. |
-
net8.0
- Microsoft.Extensions.Http (>= 8.0.0)
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 |
---|
Deprecated.