How to use IHttpClientFactory in class library

4.4k views Asked by At

I am trying to convert some code from net core api to class library.

I am stuck how to use HttpClientfactory. Normally the httpclientfactory can be configured in program.cs or Startup like

services.AddHttpClient("abc", xxx config). 

How to do configurations in class library for Httpclientfactory.

2

There are 2 answers

1
Ruikai Feng On

You could try as below:

public class HttpClientUtil
    {
        private static IServiceProvider serviceProvider { get; set; } 

        public static void Initial(IServiceProvider Provider)
        {
            if (Provider == null)
            {
                IHostBuilder builder = Host.CreateDefaultBuilder();
                builder.ConfigureServices(services =>
                {
                    services.AddHttpClient("client_1", config =>
                    {
                        config.BaseAddress = new Uri("http://client_1.com");
                        config.DefaultRequestHeaders.Add("header_1", "header_1");
                    });
                    services.AddHttpClient("client_2", config =>
                    {
                        config.BaseAddress = new Uri("http://client_2.com");
                        config.DefaultRequestHeaders.Add("header_2", "header_2");
                    });
                });
                serviceProvider = builder.Build().Services;
            }
            else
            {
                serviceProvider = Provider;
            } 
        }

        public static IHttpClientFactory GetHttpClientFactory()
        {
            if(serviceProvider==null)
            {
                Initial(serviceProvider);
            }
            return (IHttpClientFactory)serviceProvider.GetServices<IHttpClientFactory>();
        }

    }

you could get the instance of httpclinetfactory through the interface

6
mtkachenko On

In your library add an extension method for IServiceCollection to "enable" it in the main project.

In the library:

public static class ServiceCollectionExt
{
    public static void AddYourStaff(this IServiceCollection services)
    {
        services.AddHttpClient("xxx", client =>
        {
            //your staff here
        });
        services.AddSingleton<ISomethingElse, SomethingElse>();
    }
} 

Then in your Startup just call it:

services.AddYourStaff();

UPDATE: As the author described, he's working on the plugin based application. In that case you need some kind of convention, for instance:

  1. each plugin library must have a public static class called Registration with public static method Invoke(IServiceCollection sc, IConfiguration config)
  2. Then in your Startup you can iterate through all plugin libraries and call their Registration.Invoke(sc, config) using reflection:
foreach(var pluginAssembly in plugins)
{
    pluginAssembly
        .GetType("Registration")
        .GetMethod("Invoke", BindingFlags.Public | BindingFlags.Static)
        .Invoke(null, new object[] {services, Configuration});
}