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
,即服务未注册。为什么会发生这种情况?在我的代码中