Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
429 views
in Technique[技术] by (71.8m points)

nuget - In C#, How can I reuse an HttpClient for multiple services?

I've created a C# microservice which offers several different (but related) functions.

I am now creating a C# Nuget package for a client which will help other C# microservices to leverage this microservice. This will include a Service Collection Extension class to facilitate adding the client to those microservices.

In the interest of separating concerns, within the client, I've separated the functionality into three classes:

  • SalesforceCacheQuerier
  • SalesforceCacheSyncDataManipulator
  • SalesforceCacheAsyncDataManipulator

Each of these need to call out to the same server.

As a niave first implementation, I've composed this method:

        public static IServiceCollection AddSalesforceClients(this IServiceCollection services)
        {
            services.AddTransient<SalesforceCacheAuthenticationHandler>();
            ConfigureClient(services.AddHttpClient<ISalesforceCacheQuerier, SalesforceCacheQuerier>());
            ConfigureClient(services.AddHttpClient<ISalesforceCacheSyncDataManipulator, SalesforceCacheSyncDataManipulator>());
            ConfigureClient(services.AddHttpClient<ISalesforceCacheAsyncDataManipulator, SalesforceCacheAsyncDataManipulator>());
            return services;
        }

        private static IHttpClientBuilder? ConfigureClient(IHttpClientBuilder? clientBuilder)
            => clientBuilder.ConfigureHttpClient(ConfigureClient)
            .ConfigurePrimaryHttpMessageHandler(() => new SocketsHttpHandler())
            .AddHttpMessageHandler<SalesforceCacheAuthenticationHandler>();

        private static void ConfigureClient(IServiceProvider provider, HttpClient client)
        {
            SalesforceCacheSettings? settings = provider.GetRequiredService<SalesforceCacheSettings>();
            client.BaseAddress = new Uri(settings.BaseUrl, settings.ApiEndpoint);
            client.DefaultRequestHeaders.ExpectContinue = true;
        }

However, this generates three separate HttpClients and triples the traffic for the "Identity Server" used to provide Jwt tokens.

How can I refactor this to create and reuse only a single HttpClient?

question from:https://stackoverflow.com/questions/66065609/in-c-how-can-i-reuse-an-httpclient-for-multiple-services

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

You can use HttpClientFactory and inject it in ConfigureServices something like services.AddHttpClient(); Later wherever you need client object just give IHttpClientFactory httpClientFactory in the constructor and you can have access to client object by just asking the factory to create a client.

HttpClient = HttpClientFactory.CreateClient(); in this fashion.

In case if you want to hold the authentication for the clients and reuse it. I would suggest to maintain a dictionary for each request type.

var HttpClients = new Dictionary<string, HttpClient>();

HttpClients.Add(SalesforceCacheQuerierKey, SalesforceCacheQuerierClient);

//assuming all the auth related headers are added to this client object //SalesforceCacheQuerierClient

and pass these from startup level.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...