非泛型方法“IServiceProvider.GetService(Type)”不能与类型参数一起使用。

59

我正在使用.NET Core依赖注入,但是当我尝试在另一个类中获取服务时,会出现“IServiceProvider.GetService(Type)”不能与类型参数一起使用的错误。

这个错误意味着什么? 我理解通用类型参数类似于这样:GenericInterface<>,而GetService方法不接受GenericInterface<>作为参数。

我为什么会遇到这个错误,如何解决?

接口

public interface IService
{
   void Process();
}
实现该接口的类。
public class Service : BaseService<IConfig, SomType>
{
    public Service(
        ILogger logger : base(logger)
    {
    }

    ...
}

BaseService类是一个抽象类,它实现了IService接口。

public abstract class BaseService<TConfig, TE> : AnotherBaseService, IService where TConfig : IConfig where TE : struct, IConvertible
{
      protected BaseService(ILogger logger): base(logger)
      {
      } 

      ...
}
另一个基础服务
public abstract class BaseService
{
   protected readonly ILogger Logger;

   protected BaseService(ILogger logger)
   {
      Logger = logger;
   }

   ...
}

我是如何注册它们的。

serviceCollection.AddScoped<IService, Service>();

我如何获取我需要的服务。

var incoming = serviceProvider.GetService<IService>();

NB: 我刚开始接触依赖注入和 .NET Core,对 DI 还不了解所有内容。你的回答将对我有很大帮助。

4个回答

192

泛型GetService< T> 方法是一个扩展方法。这意味着您需要有:

using Microsoft.Extensions.DependencyInjection;

为了让编译器找到它,此方法仅用于可选服务。如果对象无法构造,则它将返回null,原因可能是类型未注册或其某些依赖项缺失。

GetRequiredService 应该在应用程序不能正常工作除非服务可用时使用。如果无法创建实例,它将引发一个 InvalidOperationException 异常。

当抛出异常时,完整的异常文本将对查找实际问题非常有帮助。构造函数中引发的异常可以出现在 Exception.InnerException 属性中。结束于抛出异常的调用序列将出现在 StackTrace 属性中。调用 Exception.ToString() 将返回包含当前异常和任何内部异常的全部信息的字符串。


它能运行,但现在我遇到了一个空异常。你能帮忙吗? - 57913
@Cookie 这意味着类型未注册或无法构造。如果您的应用程序无法使用特定服务,请使用 GetRequiredService< T>。如果服务注册丢失,GetRequiredService 将抛出一个异常来解释原因。有时很明显(服务未注册或构造函数抛出异常),有时则不然。 - Panagiotis Kanavos
感谢您的快速回复,@Panagiotis Kanavos。我找到了它的原因,空异常是因为“服务”正在使用的一个服务尚未注册。 - 57913
1
这个可行,谢谢。不知道为什么智能感知没有给我提示。 - cesarmart
@Frank “不起作用” 并不是很清楚。每个 .NET Core 开发者都会以某种形式使用该方法。 - Panagiotis Kanavos
显示剩余2条评论

7
这意味着您的编译器只知道采用某种类型的方法。您可以调用
var incoming = serviceProvider.GetService(typeof(IService));

或者您可以添加一个

标签。
using Microsoft.Extensions.DependencyInjection;

为了确保编译器知道允许您将类型指定为泛型参数的扩展方法,您需要安装可能需要包Microsoft.Extensions.DependencyInjection.Abstractions。请注意保留HTML标记。

1
我本来也想写完全一样的答案,但你比我快 :-) - Jcl
@nvoigt 谢谢,这个方法可行,但是我现在遇到了一个空引用异常错误,当我获取服务时。你知道可能是什么原因吗? - 57913
对我不起作用。 - Frank
@Frank,请开一个新的问题并提供详细信息,说明在您的情况下具体出了什么问题。如果不知道任何上下文,我很抱歉无法对一条评论“对我无效”做出任何回应。 - nvoigt

4

简短回答已经在上面的帖子中解释得很好:

ServiceProvider.GetService<T>(); 

使用以下命名空间时需要显式定义,而不要依赖于Intellisense。

using Microsoft.Extensions.DependencyInjection;

注意,如果在此之后出现Null异常,可能会有多个问题:

  1. 确保在启动时将HostBuilder服务设置为ServiceProvider值

    ServiceProvider = host.Services;

  2. 另一个问题可能是T类的构造函数无法解析所使用接口的依赖项。

**

谢谢!祝编码愉快 :)

**


0

你应该使用

var incoming = serviceProvider.GetService(typeof(IService));

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接