GraphQL dotnet核心查询类依赖注入

时间:2020-06-03 14:03:43

标签: c# dependency-injection graphql

更新:以前的null错误是因为创建了没有参数的Query类的空构造函数。现在,我删除了该空的构造函数,但得到一个新的错误:System.MissingMethodException: No parameterless constructor defined for type 'App.Controllers.Graphs.Query'


如何将服务注入GraphQL Query类? (基于模式的方法)

在我的dotnet core 3.1项目中,我已经安装:GraphQL.Server.Transports.AspNetCore 3.5.0-alpha0046

这是我的根图:

  public class RootGraph : Schema
  {
    public RootGraph(IServiceProvider provider) : base(provider)
    {
      var schema = For(@"
        type Player {
          _id: ID!
          dbname: String!
          isPremium: Boolean!
          games: [String]!
        }

        input PlayerView {
          dbname: String!
          isPremium: Boolean!
        }

        type Query {
          player(dbname: String!): Player
        }
      ", _ =>
      {
        _.Types.Include<Query>();
      });

      Console.WriteLine(provider); // <-- provider is not null here, everything is good

      Query = schema.Query;
    }
  }

然后我像这样创建查询类:

  public class Query
  {
    private readonly ServiceProvider serviceProvider;
    private readonly IPlayerService playerService; 

    public Query( IServiceProvider serviceProvider )
    {
      this.serviceProvider = serviceProvider as ServiceProvider;
      this.playerService = serviceProvider.GetService<IPlayerService>();
    }

    [GraphQLMetadata("player")]
    public async Task<Player> GetPlayer(string dbname)
    {
      Console.WriteLine(serviceProvider);
      Player player = await playerService.Get(dbname);
      return player;
    }
  }

但是它不起作用。无法创建Query类,因为在这里出现异常:

System.MissingMethodException: No parameterless constructor defined for type 'App.Controllers.Graphs.Query'.\r\n
at System.RuntimeType.CreateInstanceDefaultCtorSlow(Boolean publicOnly, Boolean wrapExceptions, Boolean fillCache)\r\n
at System.RuntimeType.CreateInstanceDefaultCtor(Boolean publicOnly, Boolean skipCheckThis, Boolean fillCache, Boolean wrapExceptions)\r\n
at System.Activator.CreateInstance(Type type, Boolean nonPublic, Boolean wrapExceptions)\r\n 
at System.Activator.CreateInstance(Type type)\r\n  
at GraphQL.DefaultServiceProvider.GetService(Type serviceType)\r\n

我的Startup.cs的一部分:

public void ConfigureServices(IServiceCollection services){

  ...

  // add services
  services.AddSingleton<IPlayerService, PlayerService>();

  // add GraphQL
  services.AddSingleton<RootGraph>();
  services.AddSingleton<Query>();
}

有人知道如何为Query类提供服务吗?

3 个答案:

答案 0 :(得分:0)

您必须在启动类中编写此代码。

services.AddScoped<IServiceProvider , ServiceProvider >();

并在类中声明接口类型,然后传递给构造函数。

private readonly IServiceProvider _serviceProvider ;

您可以根据要求使用AddSingletonAddTransientAddScoped

答案 1 :(得分:0)

因此,根据this thread,我要做的就是在架构配置中指定服务提供者,如下所示:

    public RootGraph(IServiceProvider provider) : base(provider)
    {
      var schema = For(@"...", _ =>
      {
        _.Types.Include<Query>();
        _.ServiceProvider = provider; // <=== Add this line here

      });

      // ...

    }

答案 2 :(得分:0)

您应该能够直接注入它,而不必使用 IServiceProvider。 像这样:

[GraphQLMetadata("Query")] 
public class Query
  {
    private readonly IPlayerService playerService; 

    public Query(IPlayerService playerService)
    {
      this.playerService = playerService;
    }

    [GraphQLMetadata("player")]
    public async Task<Player> GetPlayer(string dbname)
    {
      Console.WriteLine(serviceProvider);
      Player player = await playerService.Get(dbname);
      return player;
    }
  }

然后在您的 SchemaFile 中,您必须将 ServiceProvider 添加到您的架构中。

  public class RootGraph : Schema
  {
    public RootGraph(IServiceProvider provider) 
        : base(provider)
    {
      var schema = For(@"
        ...
      ", _ =>
      {
        _.Types.Include<Query>();
        _.ServiceProvider = provider;
      });
    }
  }