MelbourneDeveloper/RestClient.Net

Overload for dependency injection that accepts Action<CreateClientOptions, IServiceProvider>

DrLeh opened this issue · 2 comments

DrLeh commented

Update: see #99

This method doesn't pass the service provider to the action, meaning I cannot reference any other services during my registration.

public static IServiceCollection AddRestClient(this IServiceCollection serviceCollection, Action<CreateClientOptions>? configureClient = null)
{
_ = serviceCollection
.AddSingleton<CreateHttpClient>((sp) =>
{
var microsoftHttpClientFactoryWrapper = new MicrosoftHttpClientFactoryWrapper(sp.GetRequiredService<IHttpClientFactory>());
return microsoftHttpClientFactoryWrapper.CreateClient;
})
.AddSingleton<CreateClient>((sp) =>
{
var clientFactory = new ClientFactory(
sp.GetRequiredService<CreateHttpClient>(),
sp.GetService<ILoggerFactory>());
return clientFactory.CreateClient;
})
.AddSingleton((sp) => sp.GetRequiredService<CreateClient>()("RestClient", configureClient));
return serviceCollection;

For example, before using this package I register an http client like so:

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);
    ...
}

Since I use the IServiceProvider sp to get the configuration for the url, i'm not able to register my provider with RestClient.Net. This is useful because when deploying code to dev environment, i want to configure it to talk to other apis in that environment.

Here's what I envision this code looking like:

        public static IServiceCollection AddRestClient(this IServiceCollection serviceCollection, Action<CreateClientOptions, IServiceProvider>? configureClient = null)
        {
            _ = serviceCollection
            .AddSingleton<CreateHttpClient>((sp) =>
            {
                var microsoftHttpClientFactoryWrapper = new MicrosoftHttpClientFactoryWrapper(sp.GetRequiredService<IHttpClientFactory>());
                return microsoftHttpClientFactoryWrapper.CreateClient;
            })
            .AddSingleton<CreateClient>((sp) =>
            {
                var clientFactory = new ClientFactory(
                    sp.GetRequiredService<CreateHttpClient>(),
                    sp.GetService<ILoggerFactory>());

                return clientFactory.CreateClient;
            })
            .AddSingleton((sp) => sp.GetRequiredService<CreateClient>()("RestClient", x => configureClient(x, sp));

            return serviceCollection;
        }
        ```

Thanks!

@DrLeh thanks for reporting. I will get to this and the PR soon.

Hi @DrLeh . I thought you might like to know that I finally addressed the issue you logged here. I used part of your unit test from another branch, but I did not follow the same path to fix the issue. You can see how the problem was solved here:

public void DIConfigureWithInjectedService()