没有找到合适的类型构造函数
A suitable constructor of type does not be located
我正在尝试最简单的IHttpClientFactory
用例
public interface IWeatherForecast
{
Task<string> Get();
}
class WeatherForecast : IWeatherForecast
{
private readonly HttpClient httpClient;
public WeatherForecast (IHttpClientFactory httpClientFactory)
{
httpClient = httpClientFactory.CreateClient();
}
public async Task<string> Get()
{
var resp = await httpClient.GetAsync("https://testwebapiforuseinsamples.azurewebsites.net/weatherforecast");
return JsonConvert.SerializeObject(resp.Content.ReadAsStringAsync());
}
}
然后实例化它
static async Task Main(string[] args)
{
var container = new ServiceCollection();
container.AddHttpClient<IWeatherForecast, WeatherForecast>();
var serviceProvider = container.BuildServiceProvider();
var resp = await serviceProvider.GetRequiredService<WeatherForecast>().Get();
}
然而当我运行它时,它抛出
System.InvalidOperationException: 'A suitable constructor for type 'HttpClientFactoryExample.WeatherForecast' could not be located. Ensure the type is concrete ...
谁能指出这段代码有什么问题。我期望在向 DI 添加 WeatherForecast
服务后,我将能够从容器中获取它的初始化实例。
当使用像您在此处所做的那样进行抽象的类型客户端注册时
//...
container.AddHttpClient<IWeatherForecast, WeatherForecast>();
//...
它将抽象注册为客户端类型,而不是实现。
Adds the IHttpClientFactory
and related services to the IServiceCollection
and configures a binding between the TClient
type and a named HttpClient
. The client name will be set to the type name of TClient
.
引用IHttpClientBuilder AddHttpClient<TClient,TImplementation>
因为你尝试解析实现WeatherForecast
//...
var resp = await serviceProvider.GetRequiredService<WeatherForecast>().Get();
//...
它会失败,因为
System.InvalidOperationException: No service for type 'WeatherForecast' has been registered.
你应该真正解决的是抽象IWeatherForecast
//...
var resp = await serviceProvider.GetRequiredService<IWeatherForecast>().Get();
//...
容器知道映射到 WeatherForecast
实现,然后将其及其依赖项一起初始化。
解决了这个问题后,您还需要更新服务以显式依赖 HttpClient
,因为这是类型化的客户端注册
class WeatherForecast : IWeatherForecast {
private readonly HttpClient httpClient;
public WeatherForecast (HttpClient httpClient) {
this.httpClient = httpClient;
}
public async Task<string> Get() {
var resp = await httpClient.GetAsync("https://testwebapiforuseinsamples.azurewebsites.net/weatherforecast");
return JsonConvert.SerializeObject(resp.Content.ReadAsStringAsync());
}
}
引用Use IHttpClientFactory to implement resilient HTTP requests
当您在服务集合中将类型注册为 HTTP 客户端 container.AddHttpClient<IWeatherForecast, WeatherForecast>()
时,它必须在构造函数中包含 HttpClient
。在你的情况下应该是:
public WeatherForecast(HttpClient httpClient)
{
this.httpClient = httpClient;
}
另一种选择是分别注册 HttpClientFactory
和您的 WeatherForecast
服务:
container.AddHttpClient();
container.AddTransient<IWeatherForecast, WeatherForecast>();
然后将服务与 HttpClientFactory 一起使用:
private readonly HttpClient httpClient;
public WeatherForecast(IHttpClientFactory factory)
{
this.httpClient = factory.CreateClient();
}
我正在尝试最简单的IHttpClientFactory
用例
public interface IWeatherForecast
{
Task<string> Get();
}
class WeatherForecast : IWeatherForecast
{
private readonly HttpClient httpClient;
public WeatherForecast (IHttpClientFactory httpClientFactory)
{
httpClient = httpClientFactory.CreateClient();
}
public async Task<string> Get()
{
var resp = await httpClient.GetAsync("https://testwebapiforuseinsamples.azurewebsites.net/weatherforecast");
return JsonConvert.SerializeObject(resp.Content.ReadAsStringAsync());
}
}
然后实例化它
static async Task Main(string[] args)
{
var container = new ServiceCollection();
container.AddHttpClient<IWeatherForecast, WeatherForecast>();
var serviceProvider = container.BuildServiceProvider();
var resp = await serviceProvider.GetRequiredService<WeatherForecast>().Get();
}
然而当我运行它时,它抛出
System.InvalidOperationException: 'A suitable constructor for type 'HttpClientFactoryExample.WeatherForecast' could not be located. Ensure the type is concrete ...
谁能指出这段代码有什么问题。我期望在向 DI 添加 WeatherForecast
服务后,我将能够从容器中获取它的初始化实例。
当使用像您在此处所做的那样进行抽象的类型客户端注册时
//...
container.AddHttpClient<IWeatherForecast, WeatherForecast>();
//...
它将抽象注册为客户端类型,而不是实现。
Adds the
IHttpClientFactory
and related services to theIServiceCollection
and configures a binding between theTClient
type and a namedHttpClient
. The client name will be set to the type name ofTClient
.
引用IHttpClientBuilder AddHttpClient<TClient,TImplementation>
因为你尝试解析实现WeatherForecast
//...
var resp = await serviceProvider.GetRequiredService<WeatherForecast>().Get();
//...
它会失败,因为
System.InvalidOperationException: No service for type 'WeatherForecast' has been registered.
你应该真正解决的是抽象IWeatherForecast
//...
var resp = await serviceProvider.GetRequiredService<IWeatherForecast>().Get();
//...
容器知道映射到 WeatherForecast
实现,然后将其及其依赖项一起初始化。
解决了这个问题后,您还需要更新服务以显式依赖 HttpClient
,因为这是类型化的客户端注册
class WeatherForecast : IWeatherForecast {
private readonly HttpClient httpClient;
public WeatherForecast (HttpClient httpClient) {
this.httpClient = httpClient;
}
public async Task<string> Get() {
var resp = await httpClient.GetAsync("https://testwebapiforuseinsamples.azurewebsites.net/weatherforecast");
return JsonConvert.SerializeObject(resp.Content.ReadAsStringAsync());
}
}
引用Use IHttpClientFactory to implement resilient HTTP requests
当您在服务集合中将类型注册为 HTTP 客户端 container.AddHttpClient<IWeatherForecast, WeatherForecast>()
时,它必须在构造函数中包含 HttpClient
。在你的情况下应该是:
public WeatherForecast(HttpClient httpClient)
{
this.httpClient = httpClient;
}
另一种选择是分别注册 HttpClientFactory
和您的 WeatherForecast
服务:
container.AddHttpClient();
container.AddTransient<IWeatherForecast, WeatherForecast>();
然后将服务与 HttpClientFactory 一起使用:
private readonly HttpClient httpClient;
public WeatherForecast(IHttpClientFactory factory)
{
this.httpClient = factory.CreateClient();
}