Reputation: 1068
I have a set of libraries, which I want to move from PCL to netcore. With the move I want to streamline the DI system and update some internal workings.
One of the things I want to add is configuration for internal objects, much like in Asp.Net Core (i.e. services.AddMvc(opt => { /* Options Stuff*/ });
).
My current service collection extension looks like this:
public static IServiceCollection AddCore(this IServiceCollectionserviceCollection, Action<HttpClientOptions> options)
{
serviceCollection.AddSingleton<HttpClient>();
serviceCollection.Configure(options);
return serviceCollection;
}
And the configuration class looking like this:
public sealed class HttpClientOptions
{
public HttpMessageHandler MessageHandler { get; set; }
// Remaining properties omitted for brevity
}
However I'm asking myself, how I can apply the configuration to HttpClient
, since it's a framework class and I can'T modify it to take the options via constructor injection.
Is there a way to set this, or do I have to rethink my configuration approach?
Upvotes: 2
Views: 159
Reputation: 11044
serviceCollection.AddSingleton()
has an overload that takes a Func<IServiceProvider, HttpClient>
factory.
So, you could potentially do something along the lines of:
serviceCollection
.AddSingleton<HttpClient>((serviceCollectionInstance) => {
var myOptions = serviceCollectionInstance.GetRequiredService<MyHttpClientOptions>();
return new HttpClient(myOptions);
});
Or even
serviceCollection.AddSingleton<MyHttpClientFactory>(); // <-- your very own factory class that creates arbitrarily complex options
serviceCollection.AddSingleton<HttpClient>(_ => _.GetRequiredService<MyHttpClientFactory>().CreateHttpClient());
If you really wanted to go overboard, you could even write your very own extension method to achieve the fluent configuration style:
public static class ServiceCollectionExtensions
{
public static void AddHttpClient(this IServiceCollection @this, Action<HttpClientOptions> configure = null)
{
var options = new HttpClientOptions();
if (configure != null)
{
configure(options);
}
@this.AddSingleton<HttpClient>(options);
}
}
Usage:
serviceCollection.AddHttpClient(opts => {
opts.HttpMessageHandler = // etc
});
Upvotes: 2