Ruhrpottpatriot
Ruhrpottpatriot

Reputation: 1068

Netcore - Apply configurations to framework classes

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

Answers (1)

vzwick
vzwick

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

Related Questions