I am using AddHttpClient for injecting an HttpClient (using Typed clients) according to best practices in Microsoft documentation, but this approach does not allow me to configure the rest of the dependencies of my Service.
Let's say I have this setup:
public interface ISerializer { /*...*/ } public class Serializer : ISerializer { private readonly string _options; public Serializer(string options) { _options = options; } /*...*/ } public class ServiceA { private readonly HttpClient _client; private readonly ISerializer _serializer; public ServiceA(HttpClient httpClient, ISerializer serializer) { _client = httpClient ?? throw new ArgumentNullException(nameof(httpClient)); _serializer = serializer ?? throw new ArgumentNullException(nameof(serializer)); } public string MakeCall() { // var body = _serializer.Serialize(); return _client.GetAsync("").Result.StatusCode.ToString(); } } public class ServiceB { /* Similar to ServiceA */ } public static class ServiceCollectionExtensions { public static IServiceCollection AddServiceAandB(this IServiceCollection services) { /* If I do this below, Serializer("option 1") will be used in Services A and B however, what I would like is to have different Serializer's configurations for A and B (see full question below) */ services.AddTransient<ISerializer>((p) => new Serializer("option 1")); services.AddHttpClient<ServiceA>(c => { c.BaseAddress = new Uri("api-url-for-A"); c.Timeout = TimeSpan.FromSeconds(5); }); services.AddHttpClient<ServiceB>(c => { c.BaseAddress = new Uri("api-url-for-B"); c.Timeout = TimeSpan.FromSeconds(5); }); return services; } } Question: How to configure ISerializer dependency with Serializer("option 1") for ServiceA and Serializer("option 2") for ServiceB? However, because I am using AddHttpClient and it is in charge of constructing ServiceA and ServiceB itself, I am not able to configure it as I want.
NOTE: As suggested, creating multiple implementations may works for simple cases, but imagine that Serializer receive an Options object and that creating different implementations for all options combinations would be impossible. That's why I would like to configure the options during DI setup.
Any help will be appreciated.
-------- UPDATE 1 --------
I do not intend to inject two ISerializer, but rather be able to configure Serializer and while constructing ServiceA and ServiceB and take advantage of .AddHttpClient.
For example (below code is not possible, but ideal):
services.AddHttpClient<ServiceA>(c => { c.BaseAddress = new Uri("api-url-for-A"); c.Timeout = TimeSpan.FromSeconds(5); }); services.AddTransient<ServiceA>(p => { return new ServiceA(p.GetHttpClientFor<ServiceA>(), new Serializer("option 1")); }); services.AddHttpClient<ServiceB>(c => { c.BaseAddress = new Uri("api-url-for-B"); c.Timeout = TimeSpan.FromSeconds(5); }); services.AddTransient<ServiceB>(p => { return new ServiceB(p.GetHttpClientFor<ServiceB>(), new Serializer("option 2")); }); // neither IServiceProvider.GetHttpClient method exists, nor I can use .AddHttpClient with AddTransient for same dependency.
ISerializerand so different services can use different options.ISerializerin to your pipeline. Otherwise how will the framework know which one to inject in to the service that wants it.