C# 服务未在servicecollection中注册
我不明白为什么在我将服务添加到C# 服务未在servicecollection中注册,c#,asp.net-core,dependency-injection,service-provider,C#,Asp.net Core,Dependency Injection,Service Provider,我不明白为什么在我将服务添加到IServiceCollection之后,当我尝试使用ServiceProvider获取对它的引用时,该值为空 启动 public void ConfigureServices(IServiceCollection services) { Startup.ConfigureServicesForDebugging?.Invoke(services); try { services.AddTransient<HttpW
IServiceCollection
之后,当我尝试使用ServiceProvider
获取对它的引用时,该值为空
启动
public void ConfigureServices(IServiceCollection services)
{
Startup.ConfigureServicesForDebugging?.Invoke(services);
try
{
services.AddTransient<HttpWrapper>();
ServiceProvider prov = services.BuildServiceProvider();
HttpWrapper returned=prov.GetRequiredService<HttpWrapper>();
if (returned == null)
{
Console.WriteLine("is null");
}
else Console.WriteLine(returned.Test);
}
catch (Exception ex)
{
Console.WriteLine(ex);
}
}
为什么返回的服务为空?我第一次想到它是因为它的是瞬态的
所以它是每个请求的。。所以在那个阶段没有请求->null。但是当使用
AddSingleton
时它仍然返回null。
为什么那个服务是空的
p.S我需要的是:
public class TransientService{
public HttpClient sharedProperty;
}
public void ConfigureServices(IServiceCollection services)
{
HttpClient client=new HttpClient();
services.AddTransient( new TransientService{ sharedProperty=client});
}
我需要一个暂时的服务,但它的所有实例都共享一个字段(HttpClient
)
PS 2在我从
GetService
更改为GetRequiredService
后,我得到了服务未注册的InvalidOperationException
。为什么会发生这种情况?我还将插入从更改为非lambda:services.AddTransient()仍然存在相同的问题。我无法重现该问题 如果请求的服务尚未注册,
GetService
将返回null。如果调用了GetRequiredService
,它将抛出异常
这段代码中有两个问题
首先,这一行:
services.AddTransient(y =>wrapper);
注册一个工厂函数,该函数返回相同的HttpWrapper实例,而不是HttpWrapper实例本身。该函数将返回wrapper
包含的任何内容
其次,AddTransient
说这是一个临时服务,但是每次都会返回相同的实例
如果每次都使用相同的服务,则注册应使用AddSingleton
:
services.AddSingleton<HttpWrapper>();
将确保CatalogService
的每个实例都将得到正确处理的HttpClient
。CatalogService需要做的就是在其构造函数中接受一个HttpClient
,并在其方法中使用它:
public class CatalogService : ICatalogService
{
private readonly HttpClient _httpClient;
public CatalogService(HttpClient httpClient)
{
_httpClient = httpClient;
}
public async Task<Catalog> GetCatalogItems(int page, int take,
int? brand, int? type)
{
....
var responseString = await _httpClient.GetStringAsync(uri);
...
}
}
并在AddHttpClient
中注册:
services.AddHttpClient<HttpWrapper>();
services.AddHttpClient();
之后,可通过以下方式解决:
var returned = prov.GetRequiredService<HttpWrapper>();
var returned=prov.GetRequiredService();
我无法重现这个问题
如果请求的服务尚未注册,GetService
将返回null。如果调用了GetRequiredService
,它将抛出异常
这段代码中有两个问题
首先,这一行:
services.AddTransient(y =>wrapper);
注册一个工厂函数,该函数返回相同的HttpWrapper实例,而不是HttpWrapper实例本身。该函数将返回wrapper
包含的任何内容
其次,AddTransient
说这是一个临时服务,但是每次都会返回相同的实例
如果每次都使用相同的服务,则注册应使用AddSingleton
:
services.AddSingleton<HttpWrapper>();
将确保CatalogService
的每个实例都将得到正确处理的HttpClient
。CatalogService需要做的就是在其构造函数中接受一个HttpClient
,并在其方法中使用它:
public class CatalogService : ICatalogService
{
private readonly HttpClient _httpClient;
public CatalogService(HttpClient httpClient)
{
_httpClient = httpClient;
}
public async Task<Catalog> GetCatalogItems(int page, int take,
int? brand, int? type)
{
....
var responseString = await _httpClient.GetStringAsync(uri);
...
}
}
并在AddHttpClient
中注册:
services.AddHttpClient<HttpWrapper>();
services.AddHttpClient();
之后,可通过以下方式解决:
var returned = prov.GetRequiredService<HttpWrapper>();
var returned=prov.GetRequiredService();
您注册的是功能,而不是服务。函数每次返回相同的实例,就好像它是一个单例一样。您想做什么?我需要添加一个瞬态的HttpWrapper
实例。我想您可以使用委托重载作为构建服务的自定义方式。如果是一个实例,它就不是瞬态的。这个重载注册了一个工厂方法,但在本例中,它返回相同的实例,使其成为一个单例,这是相同的矛盾语句。如果您的意思是我想创建一个正确使用httpclient的类型化httpclient
,那么您做得不对。有几篇文章解释了如何使用HttpClientFactory进行此操作以及为什么要这样做-如果DNS到IP映射发生更改,HttpClient将停止工作。@Bercoviciarian这篇文章介绍了如何创建一个正确处理HttpClient的类型化Http客户端。只需一行services.AddHttpClient()
就可以为包装器/服务类获得正确的生命周期处理您注册的是函数,而不是服务。函数每次返回相同的实例,就好像它是一个单例一样。您想做什么?我需要添加一个瞬态的HttpWrapper
实例。我想您可以使用委托重载作为构建服务的自定义方式。如果是一个实例,它就不是瞬态的。这个重载注册了一个工厂方法,但在本例中,它返回相同的实例,使其成为一个单例,这是相同的矛盾语句。如果您的意思是我想创建一个正确使用httpclient的类型化httpclient
,那么您做得不对。有几篇文章解释了如何使用HttpClientFactory进行此操作以及为什么要这样做-如果DNS到IP映射发生更改,HttpClient将停止工作。@Bercoviciarian这篇文章介绍了如何创建一个正确处理HttpClient的类型化Http客户端。使用一行services.AddHttpClient()
您可以为包装器/服务类获得正确的生命周期处理在我的代码中,在我使用服务提供程序之前,我已将服务添加到集合中。我需要一个实例,它不会选择哪个实例。我也尝试过使用AddSingleton
,但它仍然返回一个null
。我需要任何该实例特定类型的服务。@Bercovicadrian您注册了一个返回单个实例的工厂方法。在任何情况下,无需重新注册。当我像您所说的那样在我的代码上使用GetRequiredService
时,我会得到InvalidOperationException
,即服务未注册。为什么会发生这种情况?在我的代码中