public static IHttpClientBuilder AddApiClient <TClient, TOptions>(this IServiceCollection services, Action <TOptions> configureClient = null, IKnownErrorParser <TClient> errorParser = null)
            where TClient : ApiClient <TClient>
            where TOptions : ApiClientOptions <TClient>, new()
        {
            if (services == null)
            {
                throw new ArgumentNullException(nameof(services));
            }
            //if (configureClient == null) throw new ArgumentNullException(nameof(configureClient));

            // I Preferred to just call Invoke on configureClient rather than add another service just to retrieve it later!
            //services.Configure<TOptions>(configureClient);

            // Add the options class to the DI container for use later
            //services.AddSingleton<TOptions>(); // Previous code, removed to avoid duplication in the DI container

            var scopeFactory = services.BuildServiceProvider().GetRequiredService <IServiceScopeFactory>();

            using (var scope = scopeFactory.CreateScope())
            {
                // Get the Service Provider
                var provider = scope.ServiceProvider;
                // Get a logger for the type of ApiClient we are creating
                var logger = provider.GetRequiredService <ILogger <TClient> >();

                // Get a customised ApiClientOptions class from DI container if available
                //TOptions options = provider.GetRequiredService<TOptions>(); // Previous code

                // new up the options then add the configured instance to the DI container later
                TOptions options = new TOptions();

                // If we have a configuration registered in DI (usually from config files) use it to configure the options
                var configureOptions = provider.GetService <IConfigureOptions <TOptions> >();
                if (configureOptions != null)
                {
                    configureOptions.Configure(options);
                }

                // The configuration actions passed in to this method override the configuration registered in DI
                configureClient?.Invoke(options);

                if (errorParser != null)
                {
                    // Use the specified error parser first if provided
                    options.KnownErrorParsers = new List <IKnownErrorParser <TClient> >();
                    options.KnownErrorParsers.Add(errorParser);
                }
                else
                {
                    // Populate any error parsers from the Service collection
                    IEnumerable <IKnownErrorParser <TClient> > errorParsers = provider.GetServices <IKnownErrorParser <TClient> >();
                    options.KnownErrorParsers = errorParsers.ToList();
                }

                // Add the Problem Details error parser after the supplied ones
                // This will be the last one in the list, the default fallback error parser
                var problemDetailsErrorParserLogger = provider.GetRequiredService <ILogger <ProblemDetailsErrorParser <TClient> > >();
                options.KnownErrorParsers.Add(new ProblemDetailsErrorParser <TClient>(problemDetailsErrorParserLogger));

                // Create the builder and configure
                var builder = new ApiClientBuilder <TClient>(services, options, logger);

                // Save the configured options into the service collection for later use by the ApiClient
                // Due to this ServiceScope, this needs to be done even if we pulled the options from DI in the first place
                services.AddSingleton <TOptions>(options);

                // Finally configure the client
                return(builder.ConfigureApiClient());
            }
        }
 public static IHttpClientBuilder AddApiClient <TClient>(this IServiceCollection services, Action <ApiClientOptions <TClient> > configureClient = null, IKnownErrorParser <TClient> errorParser = null)
     where TClient : ApiClient <TClient>
 {
     return(AddApiClient <TClient, ApiClientOptions <TClient> >(services, configureClient));
 }