AugusteVN.HttpClient 1.1.4

Suggested Alternatives

AugusteVN.HttpClient.Delegator

The owner has unlisted this package. This could mean that the package is deprecated, has security vulnerabilities or shouldn't be used anymore.
dotnet add package AugusteVN.HttpClient --version 1.1.4
                    
NuGet\Install-Package AugusteVN.HttpClient -Version 1.1.4
                    
This command is intended to be used within the Package Manager Console in Visual Studio, as it uses the NuGet module's version of Install-Package.
<PackageReference Include="AugusteVN.HttpClient" Version="1.1.4" />
                    
For projects that support PackageReference, copy this XML node into the project file to reference the package.
<PackageVersion Include="AugusteVN.HttpClient" Version="1.1.4" />
                    
Directory.Packages.props
<PackageReference Include="AugusteVN.HttpClient" />
                    
Project file
For projects that support Central Package Management (CPM), copy this XML node into the solution Directory.Packages.props file to version the package.
paket add AugusteVN.HttpClient --version 1.1.4
                    
#r "nuget: AugusteVN.HttpClient, 1.1.4"
                    
#r directive can be used in F# Interactive and Polyglot Notebooks. Copy this into the interactive tool or source code of the script to reference the package.
#:package AugusteVN.HttpClient@1.1.4
                    
#:package directive can be used in C# file-based apps starting in .NET 10 preview 4. Copy this into a .cs file before any lines of code to reference the package.
#addin nuget:?package=AugusteVN.HttpClient&version=1.1.4
                    
Install as a Cake Addin
#tool nuget:?package=AugusteVN.HttpClient&version=1.1.4
                    
Install as a Cake Tool

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 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. 
Compatible target framework(s)
Included target framework(s) (in package)
Learn more about Target Frameworks and .NET Standard.

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.