如何访问 lambda 实现工厂中注册的 HttpClient 服务?

问题描述 投票:0回答:1

我一直在尝试研究这个问题,但一无所获。我一直在尝试使用其他问题中的元素:

使用工厂模式进行 ASP.NET Core 依赖注入

在IServiceProvider上,GetRequiredService和GetService方法有什么区别?

ASP.NET Core DI:如果作用域服务同时注册为服务类型和实现类型,则解析相同的实例

这有点令人困惑,没有人有一个与我试图实现的目标完全匹配的示例。

我有类似于以下的代码:

中间件.cs


public static IServiceCollection UseAPI(thisIServiceCollection services, string key, string username, bool test = false)
{
    services.AddHttpClient<ApiClient>(client =>
    {
        // ... setting BaseAddress based on test, adding auth headers, etc
    });
    return services.AddScoped<ApiClient>(x =>
    {
        var service = x.GetRequiredService<HttpClient>();
        var ApiClient client = new ApiClient(service);
        client.Configure(key);
        return client;
    }
}

程序.cs


services.UseAPI(_settings.Key, _settings.Username, _settings.IsTest);

ApiClient.cs


public class ApiClient
{
    private readonly HttpClient httpClient;
    private string Key;
    public ApiClient(HttpClient _httpClient)
    {
        httpClient = _httpClient;
    }

    public void Configure(string key)
    {
        Key = key;
    }
}

Key
值用作创建内容签名过程的一部分,因此无法添加到默认标头中。我似乎不知道如何从中间件获取密钥。当然,我可以注入配置并以这种方式获取它,但这不是可移植的,而且我将其构建为一个包,因此尽量减少对它的依赖将是理想的。

c# dependency-injection dotnet-httpclient
1个回答
0
投票

目前您正在尝试注册您的

ApiClient
两次。

services.AddHttpClient<ApiClient>()
配置一个命名的
HttpClient
实例,该实例将传递给
ApiClient
构造函数 并且
ApiClient
添加到您的服务集合中。之后无需再调用
AddScoped
。请参阅类型化客户端

AddHttpClient<TClient,TImplementation>(IServiceCollection, String, Func<HttpClient,IServiceProvider,TImplementation>)
HttpClient
超载适用于您的情况:

services.AddHttpClient<ApiClient, ApiClient>((httpClient, serviceProvider) =>
{
    var apiClient = new ApiClient(httpClient);
    apiClient.Configure(key);
    return apiClient;
});

我还会考虑使用 Options Pattern 来注入密钥(和其他设置)。

services.AddOptions<ApiClientOptions>()
    .Configure(options => options.Key = key);

services.AddHttpClient<ApiClient>(httpClientOptions =>
{
    // Configure HTTP Client
});

// or something like
services.AddHttpClient<ApiClient>((serviceProvider, httpClientOptions) =>
{
    var options = serviceProvider.GetRequiredService<IOptions<ApiClientOptions>>();
    // Configure HTTP Client
});

public class ApiClientOptions
{
    public string Key { get; set; }
} 

public class ApiClient
{
    private readonly HttpClient _httpClient;
    private readonly string _key;
    public ApiClient(HttpClient httpClient, IOptions<ApiClientOptions> options)
    {
        _httpClient = httpClient;
        _key = options.Value.Key;
    }
}

还有一个建议:这是DI服务注册/配置注入而不是middeware,方法名称

AddApi
UseApi

更合适
© www.soinside.com 2019 - 2024. All rights reserved.