You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

面向ASP.NET Core的SDK中HttpClient最优使用方案咨询

最优解决方案

方案1:适配ASP.NET Core DI场景(推荐)

核心思路是封装ASP.NET Core依赖注入扩展方法,将HttpClient的代理、超时、请求头等自定义配置逻辑完全收敛在SDK内部,同时复用官方HttpClientFactory的能力,既不需要使用者手动传入HttpClient,也完美规避Socket耗尽、DNS更新不及时的问题。

  1. 首先在SDK项目中引入Microsoft.Extensions.Http NuGet包,编写DI扩展方法:
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Options;
using System.Net;

public class SomeSdkSettings
{
    public string ApiBaseUrl { get; set; }
    public int Timeout { get; set; } = 30;
    public string ProxyAddress { get; set; }
    public bool UseProxy { get; set; }
}

public static class SomeSdkServiceCollectionExtensions
{
    public static IServiceCollection AddSomeSdk(this IServiceCollection services, Action<SomeSdkSettings> configure)
    {
        // 注册用户传入的SDK配置
        services.Configure(configure);

        // 为SDK配置专属HttpClient,所有自定义逻辑全部在SDK内部完成
        services.AddHttpClient<ISomeSdk, SomeSdk>((sp, client) =>
        {
            var settings = sp.GetRequiredService<IOptions<SomeSdkSettings>>().Value;
            client.BaseAddress = new Uri(settings.ApiBaseUrl);
            client.Timeout = TimeSpan.FromSeconds(settings.Timeout);
            client.DefaultRequestHeaders.Add("X-Sdk-Version", "1.0.0");
            // 其他请求头、默认配置等
        })
        .ConfigurePrimaryHttpMessageHandler(sp =>
        {
            var settings = sp.GetRequiredService<IOptions<SomeSdkSettings>>().Value;
            return new HttpClientHandler
            {
                Proxy = settings.UseProxy ? new WebProxy(settings.ProxyAddress) : null,
                UseProxy = settings.UseProxy
            };
        });

        return services;
    }
}
  1. 调整SDK实现,提供DI专用构造函数:
public interface ISomeSdk
{
    Task<string> GetSomethingFromApiAsync();
}

public class SomeSdk : ISomeSdk
{
    private readonly HttpClient _httpClient;

    // DI场景专用构造函数,注入的HttpClient已经由Factory完成所有自定义配置
    public SomeSdk(HttpClient httpClient)
    {
        _httpClient = httpClient;
    }

    public async Task<string> GetSomethingFromApiAsync()
    {
        return await _httpClient.GetStringAsync("target/endpoint");
    }
}
  1. 使用者仅需在ASP.NET Core项目的启动代码中一行注册即可,无需关心HttpClient的配置逻辑:
// Program.cs中注册
builder.Services.AddSomeSdk(options =>
{
    options.ApiBaseUrl = "https://your-api-domain.com";
    options.Timeout = 15;
    // 其他SDK配置项
});

// 业务代码中直接注入使用
public class SomeController : ControllerBase
{
    private readonly ISomeSdk _someSdk;

    public SomeController(ISomeSdk someSdk)
    {
        _someSdk = someSdk;
    }
}

方案2:兼容非DI/非ASP.NET Core场景

如果你的SDK需要支持控制台、桌面应用等没有内置HttpClientFactory的场景,可以通过显式配置SocketsHttpHandler的PooledConnectionLifetime参数,解决单例SDK下的DNS更新不及时问题,不需要使用者做额外配置:

public class SomeSdk : ISomeSdk
{
    private readonly HttpClient _httpClient;

    // 非DI场景专用构造函数,内部自行完成所有HttpClient配置
    public SomeSdk(SomeSdkSettings settings)
    {
        var handler = new SocketsHttpHandler
        {
            // 设置连接池生命周期,到期自动回收旧连接,适配DNS变更
            PooledConnectionLifetime = TimeSpan.FromMinutes(2),
            Proxy = settings.UseProxy ? new WebProxy(settings.ProxyAddress) : null,
            UseProxy = settings.UseProxy
        };

        _httpClient = new HttpClient(handler, disposeHandler: true)
        {
            BaseAddress = new Uri(settings.ApiBaseUrl),
            Timeout = TimeSpan.FromSeconds(settings.Timeout)
        };
    }

    // DI场景构造函数
    public SomeSdk(HttpClient httpClient)
    {
        _httpClient = httpClient;
    }

    public async Task<string> GetSomethingFromApiAsync()
    {
        return await _httpClient.GetStringAsync("target/endpoint");
    }
}

以上两种方案都可以完全保留SDK内部对HttpClient的配置控制权,同时规避Socket耗尽和DNS更新不及时的问题,无需使用者额外处理HttpClient相关逻辑。

内容的提问来源于stack exchange,提问作者Adam Hrouda

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.05 10:54:00