我一直在尝试研究这个问题,但一无所获。我一直在尝试使用其他问题中的元素:
在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
值用作创建内容签名过程的一部分,因此无法添加到默认标头中。我似乎不知道如何从中间件获取密钥。当然,我可以注入配置并以这种方式获取它,但这不是可移植的,而且我将其构建为一个包,因此尽量减少对它的依赖将是理想的。
目前您正在尝试注册您的
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
更合适