Skip to content

Overload for dependency injection that accepts IServiceProvider  #103

@DrLeh

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!

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