Skip to content

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

Closed

Description

@DrLeh

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!

Activity

  1. changed the title [-]Overload for rest client that accepts Action<CreateClientOptions, IServiceProvider>[/-] [+]Overload for dependency injection that accepts Action<CreateClientOptions, IServiceProvider>[/+] on Aug 11, 2021
  2. MelbourneDeveloper commented on Aug 12, 2021

    @MelbourneDeveloper
    Owner

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

  3. MelbourneDeveloper commented on Apr 9, 2022

    @MelbourneDeveloper
    Owner

    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()

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