System.InvalidOperationException:找不到类型“X”的合适构造函数。确保类型是具体的,并且公共构造函数的所有参数都注册为服务或作为参数传递。还要确保没有提供无关的参数。
如何解决?这很容易。但首先,让我向您展示我在错误版本中做了什么。
设置错误的示例
对于此示例,我创建了一个基本项目。
这是一个 .NET 7 API 项目,只有一个控制器,它调用接口中定义的另一个服务。GenderController
IGenderizeService
public interface IGenderizeService
{
Task<GenderProbability> GetGenderProbabiliy(string name);
}
IGenderizeService
由一个类实现,该类是加载失败的类,因此会导致引发异常。该类调用外部终结点,分析结果,然后将其返回给调用方:GenderizeService
public class GenderizeService : IGenderizeService
{
private readonly IHttpClientFactory _httpClientFactory;
public GenderizeService(IHttpClientFactory httpClientFactory)
{
_httpClientFactory = httpClientFactory;
}
public async Task<GenderProbability> GetGenderProbabiliy(string name)
{
var httpClient = _httpClientFactory.CreateClient();
var response = await httpClient.GetAsync($"?name={name}");
var result = await response.Content.ReadFromJsonAsync<GenderProbability>();
return result;
}
}
最后,我在 Program 类中定义了服务,然后指定了哪个是在类中生成的 HttpClient 实例的基本 URL:GenderizeService
// some code
builder.Services.AddScoped<IGenderizeService, GenderizeService>();
builder.Services.AddHttpClient<IGenderizeService, GenderizeService>(
client => client.BaseAddress = new Uri("https://api.genderize.io/")
);
var app = builder.Build();
// some more code
That's it! Can you spot the error?
2 ways to solve the error
The error was quite simple, but it took me a while to spot:
In the constructor I was injecting an :IHttpClientFactory
public GenderizeService(IHttpClientFactory httpClientFactory)
while in the host definition I was declaring an for a specific class:HttpClient
builder.Services.AddHttpClient<IGenderizeService, GenderizeService>
Apparently, even if we've specified how to create an instance for a specific class, we could not build it using an IHttpClientFactory.
So, here are 2 ways to solve it.
Use named HttpClient in HttpClientFactory
Named HttpClients are a helpful way to define a specific HttpClient and use it across different services.
It's as simple as assigning a name to an HttpClient instance and then using the same name when you need that specific client.
So, define it in the Startup method:
builder.Services.AddHttpClient("genderize",
client => client.BaseAddress = new Uri("https://api.genderize.io/")
);
and retrieve it using :CreateClient
public GenderizeService(IHttpClientFactory httpClientFactory)
{
_httpClientFactory = httpClientFactory;
}
public async Task<GenderProbability> GetGenderProbabiliy(string name)
{
var httpClient = _httpClientFactory.CreateClient("genderize");
var response = await httpClient.GetAsync($"?name={name}");
var result = await response.Content.ReadFromJsonAsync<GenderProbability>();
return result;
}
原创文章,作者:ItWorker,如若转载,请注明出处:https://blog.ytso.com/292895.html