Injecting services into a custom HttpClient is a common practice in Blazor applications, especially when dealing with secure API calls, logging, or request customization. For example, in a blog platform, API requests might need authentication tokens, custom headers, or logging—all of which can be managed through a custom HttpClient service.

Why Inject Services into a Custom HttpClient?

In real-world Blazor apps, API calls often need to:

  • Include a JWT or session token for authentication
  • Log outgoing requests or responses
  • Set custom headers like X-Blog-App
  • Handle retry logic or transient faults

To achieve this cleanly, you can wrap HttpClient inside a custom service and inject any needed dependencies, like a token provider or logger.

How to Inject Services in Blazor Custom HttpClients?

Step 1: Create a BlogApiClient Service

using System.Net.Http.Headers;
using System.Net.Http.Json;
using BlogExample.Models;
public class BlogApiClient
{ private readonly HttpClient _httpClient; private readonly ITokenService _tokenService; public BlogApiClient(HttpClient httpClient, ITokenService tokenService) { _httpClient = httpClient; _tokenService = tokenService; } public async Task<List<BlogPost>> GetAllPostsAsync() { var token = await _tokenService.GetTokenAsync(); _httpClient.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", token); return await _httpClient.GetFromJsonAsync<List<BlogPost>>("api/blogposts"); } public async Task<HttpResponseMessage> CreatePostAsync(BlogPost post) { var token = await _tokenService.GetTokenAsync(); _httpClient.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", token); return await _httpClient.PostAsJsonAsync("api/blogposts", post); }
}

Step 2: Create a Token Service

public interface ITokenService
{ Task<string> GetTokenAsync();
}
public class FakeTokenService : ITokenService
{ public Task<string> GetTokenAsync() { // Simulated token, replace with real implementation return Task.FromResult("your-fake-jwt-token-here"); }
}

Step 3: Register Services in Program.cs

builder.Services.AddScoped<ITokenService, FakeTokenService>();
builder.Services.AddHttpClient<BlogApiClient>(client =>{ client.BaseAddress = new Uri("https://your-api-base-url.com/");
});

Step 4: Use BlogApiClient in a Razor Component

@inject BlogApiClient ApiClient
<h3>All Blog Posts</h3>@if (posts == null)
{ <p><em>Loading...</em></p>}
else
{ <ul class="list-group"> @foreach (var post in posts) { <li class="list-group-item"> <strong>@post.Title</strong><br /> @post.Content.Substring(0, Math.Min(post.Content.Length, 100))... </li> } </ul>}
@code { private List<BlogPost> posts; protected override async Task OnInitializedAsync() { posts = await ApiClient.GetAllPostsAsync(); }
}

Conclusion

By creating a custom HttpClient wrapper and injecting services like a token provider, you can build cleaner, more testable Blazor components. This approach also keeps your API logic centralized and consistent across the app. Whether you’re building a blog platform or an enterprise dashboard, this pattern scales well for real-world use cases.