【问题标题】:The non-generic method 'IServiceProvider.GetService(Type)' cannot be used with type arguments非泛型方法“IServiceProvider.GetService(Type)”不能与类型参数一起使用
【发布时间】:2019-01-16 12:18:21
【问题描述】:

我正在使用 .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)
      {
      } 

      ...
}

AnotherBaseService

public abstract class BaseService
{
   protected readonly ILogger Logger;

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

   ...
}

我是如何注册它们的。

serviceCollection.AddScoped<IService, Service>();

我如何获得所需的服务。

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

注意:我刚开始使用依赖注入、.NET Core,还不知道关于 DI 的一切。你的回答会有很大帮助。

【问题讨论】:

    标签: c# .net-core console-application dependency-inversion


    【解决方案1】:

    通用GetService< T> 方法是一种扩展方法。这意味着你需要有一个:

    using Microsoft.Extensions.DependencyInjection;
    

    允许编译器找到它。

    此方法仅适用于可选服务。如果无法构造对象,它将返回null,因为该类型未注册或缺少某些依赖项。

    GetRequiredService 应在应用程序无法运行时使用,除非服务可用。如果无法创建实例,则会抛出 InvalidOperationException。

    当该异常被抛出时,完整的异常文本将是一个巨大帮助找到实际问题的帮助。构造函数中抛出的异常可以出现在Exception.InnerException 属性中。最终引发异常的调用序列将出现在StackTrace 属性中。调用Exception.ToString() 将返回一个字符串,其中包含当前异常和任何内部异常的所有信息。

    【讨论】:

    • 它工作,但我现在有一个空异常。你能帮忙吗?
    • @Cookie 这意味着该类型未注册或无法构造。如果您的应用程序无法使用特定服务,请使用GetRequiredService&lt; T&gt;。如果服务注册丢失,GetRequiredService 将抛出异常解释原因。有时很清楚(服务未注册或构造函数抛出),有时不是
    • @Cookie 以帮助您解决特定情况,您必须发布重现问题的代码。如果您尝试GetRequiredService 发布完整的异常文本,由Exception.ToString() 返回
    • 感谢您的快速回复@Panagiotis Kanavos。找到了原因,出现null异常是因为“Service”正在使用的服务没有注册。
    • 这行得通,谢谢。出于某种原因,智能感知没有给我提示
    【解决方案2】:

    这意味着您的编译器只知道采用类型的方法。

    你可以打电话

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

    或者你可以添加一个

    using Microsoft.Extensions.DependencyInjection;
    

    确保您的编译器知道允许您将类型指定为泛型参数的扩展方法。这可能需要安装包Microsoft.Extensions.DependencyInjection.Abstractions

    【讨论】:

    • 我开始写 exact 相同的答案,但你更快:-)
    • @nvoigt 谢谢,这有效,我现在在获取服务时遇到空异常错误。你知道是什么原因造成的吗?
    • 对我不起作用。\
    • @Frank 请用details打开一个新问题,在您的上下文中究竟是什么不起作用。在不知道任何上下文的情况下,恐怕我对“不适合我”的评论无能为力。
    【解决方案3】:

    在上面的帖子中很好地解释了简短的答案:

    ServiceProvider.GetService<T>(); 
    

    使用以下需要明确定义的命名空间,而不是依赖于智能感知

    using Microsoft.Extensions.DependencyInjection;
    

    另外请注意,如果在此之后出现 null 异常,可能会出现多个问题:

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

      ServiceProvider = host.Services;

    2. 其他可能是 T 类的构造函数无法解析正在使用的接口的依赖关系。

    **

    谢谢!快乐编码:)

    **

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2011-10-19
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-07-01
      • 1970-01-01
      相关资源
      最近更新 更多