Skip to content

Overload for dependency injection that accepts IServiceProvider  #103

Description

@DrLeh

Update: see #104

There are currently no overloads in the dependency injection that allow resolving the base uri from a service.

For example, the code I have now before using this library registers an http client like so, where it resolves the base url out of a configuration object.

            services.AddHttpClient(MyAppClient.HttpClientName, (sp, client) =>
            {
                var config = sp.GetRequiredService<IMyAppConfiguration>();
                if (config.BaseUrl == null)
                    throw new InvalidOperationException("MyApp:BaseUrl must be configured");
                client.BaseAddress = new Uri(config.BaseUrl);

This gives me control to change the base url from config without having to resolve a configuration object during service collection registration.

public static RestClientFactoryConfig AddRestClient(this IServiceCollection services, string name, string baseUri, Headers defaultRequestHeaders)
{
if (string.IsNullOrWhiteSpace(name)) throw new ArgumentException("name cannot be empty", nameof(name));
services.TryAddSingleton<IRestClientFactory, RestClientFactory>();
var httpClientBuilder = services.AddHttpClient(name);
var config = new RestClientFactoryConfig(httpClientBuilder);
services.AddSingleton(serviceProvider => new RestClientContainer(serviceProvider, name, baseUri, defaultRequestHeaders));
return config;

I would propose that this file be amended to have an overload like so:

public static RestClientFactoryConfig AddRestClient(this IServiceCollection services, string name, Func<IServiceProvider, string> baseUriLoader, Headers defaultRequestHeaders)
{
    if (string.IsNullOrWhiteSpace(name)) throw new ArgumentException("name cannot be empty", nameof(name));
    
    services.TryAddSingleton<IRestClientFactory, RestClientFactory>();

    var httpClientBuilder = services.AddHttpClient(name);
    var config = new RestClientFactoryConfig(httpClientBuilder); 
    
    services.AddSingleton(serviceProvider => new RestClientContainer(serviceProvider, name, baseUriLoader(serviceProvider), defaultRequestHeaders));

    return config;
}

As well as other overloads for making name and headers optional.

Which would then allow a registration like so:

services.AddRestClient(sp => 
{
    var config = sp.GetRequiredService<IMyAppConfiguration>();
    if (config.BaseUrl == null)
        throw new InvalidOperationException("MyApp:BaseUrl must be configured");
    return config.BaseUrl;
});

Thanks!

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions