.net core 中的 Web Api 找不到 GraphQL 所需的服务

Web Api in .net core can't find required service for GraphQL

我有一个正在处理的 api 并且我将 运行 保留在这个错误中:

InnerException
{"Required service for type GraphQL.Types.InterfaceGraphType1[CardSortApiV3.Domain.DTO.ContactDTO] not found"} System.Exception {System.InvalidOperationException}

我在各自的文件中有以下代码: StartUp.cs

public void ConfigureServices(IServiceCollection services)
{
    services.AddControllers();
    services.AddScoped<IDocumentExecuter, DocumentExecuter>();
    services.AddScoped<IDocumentWriter, DocumentWriter>();
    services.AddScoped<ProjectQuery>();
    services.AddScoped<ContactQuery>();
    services.AddScoped<MainQuery>();
    services.AddScoped<ProjectType>();
    services.AddScoped<ContactType>();
    services.AddScoped<ContactDTO>();
    services.AddScoped<ISchema, GraphQLProjectSchema>();
    services.AddDbContext<cardsortsoftwaresContext>();
    services.AddScoped<IProjectService, ProjectService>();
    services.AddScoped<IProjectRepository, ProjectRepository>();
}

ContactQuery.cs

public class ContactQuery : ObjectGraphType
{
    public ContactQuery()
    {
        int id = 0;
        Field<ListGraphType<ContactType>>(
            name: "contacts", resolve: context =>
            {
                return /*projectService.GetProjects()*/ null;
            });
        Field<ContactType>(
            name: "project",
            arguments: new QueryArguments(new QueryArgument<IntGraphType> { Name = "id" }),
            resolve: context =>
            {
                id = (int)context.Arguments["id"].Value;
                return /*projectService.GetProjectById(id)*/ null;
            });
    }
}

ProjectQuery.cs

public class ProjectQuery : ObjectGraphType<object>
{
    public ProjectQuery(IProjectService projectService)
    {
        Name = "Query";
        int id = 0;
        Field<ListGraphType<ProjectType>>(
            name: "projects", resolve: context =>
            {
                return projectService.GetProjects();
            });
        Field<ProjectType>(
            name: "project",
            arguments: new QueryArguments(new QueryArgument<IntGraphType> { Name = "id" }),
            resolve: context =>
            {
                id = (int)context.Arguments["id"].Value;
                return projectService.GetProjectById(id);
            });
    }
}

MainQuery.cs

public MainQuery()
{
    Field<ProjectQuery>("projects", resolve:context =>
    {
        return new {};
    });
    Field<ContactQuery>("contacts", resolve: context =>
    {
        return new {};
    });
}

Schema.cs

public class GraphQLProjectSchema:Schema, ISchema
{
    public GraphQLProjectSchema(IServiceProvider resolver):base(resolver)
    {
        Query = resolver.GetService<MainQuery>();
    }
}

我花了最后 4 个小时研究和寻找答案,但没有任何效果。一切正常,直到我尝试将链接 Contact 添加到 Project.

如有任何帮助,我们将不胜感激。

编辑: 我今天早上意识到,如果我也提供类型文件可能会有所帮助。

ContactType.cs

public class ContactType : ObjectGraphType<ContactDTO>
{
    public ContactType()
    {
        Name = "Contact";
        Field(_ => _.Id).Description("Contact Id");
        Field(_ => _.FullName).Description("Contact Name");
        Field(_ => _.Email).Description("Contact Email");
        Field(_ => _.Phone).Description("Phone number for contact");
    }
}

ProjectType.cs

public class ProjectType : ObjectGraphType<ProjectDTO>
{
    public ProjectType()
    {
        Name = "Project";
        Field(_ => _.Id).Description("Project Id");
        Field(_ => _.Title).Description("Project Title");
        Field(_ => _.Description).Description("Project Description");
        Field(_ => _.ConfirmationCode).Description("Project Confirmation Code");
        Field(_ => _.Options).Description("Project Options (\"As a comma separated list\")");
        Field(_ => _.ProjectStatus).Description("Project Status (\"As an integer\")");
        Field(_ => _.CreatedTime).Description("Project Creation Time");
        Field(_ => _.UpdatedTime).Description("Project Update Time");
        Field(_ => _.EstimatedCompletion).Description("Estimated Completion Date");
        Field<InterfaceGraphType<ContactDTO>>("contact", "The contact that requested this project");
    }
}

我实际上找到了答案,虽然一开始它看起来并不奏效。

Startup.cs

    public void ConfigureServices(IServiceCollection services)
    {
        services.AddControllers();
        services.AddScoped<IDocumentExecuter, DocumentExecuter>();
        services.AddScoped<IDocumentWriter, DocumentWriter>();
        services.AddScoped<ProjectQuery>();
        services.AddScoped<ContactQuery>();
        services.AddScoped<MainQuery>();
        services.AddScoped<ProjectType>();
        services.AddScoped<ContactType>(); // This was already provided
        services.AddScoped<ISchema, GraphQLProjectSchema>();
        services.AddDbContext<cardsortsoftwaresContext>();
        services.AddScoped<IProjectService, ProjectService>();
        services.AddScoped<IProjectRepository, ProjectRepository>();
    }

然后在ProjectType.cs

    public ProjectType()
    {
        Name = "Project";
        Field(_ => _.Id).Description("Project Id");
        Field(_ => _.Title).Description("Project Title");
        Field(_ => _.Description).Description("Project Description");
        Field(_ => _.ConfirmationCode).Description("Project Confirmation Code");
        Field(_ => _.Options).Description("Project Options (\"As a comma separated list\")");
        Field(_ => _.ProjectStatus).Description("Project Status (\"As an integer\")");
        Field(_ => _.CreatedTime).Description("Project Creation Time");
        Field(_ => _.UpdatedTime).Description("Project Update Time");
        Field(_ => _.EstimatedCompletion).Description("Estimated Completion Date");
        /* Notice here that I am now requesting ContactType rather than ObjectGraphType<ContactDTO>*/
        Field<ContactType>("contact", "The contact that requested this project");
    }

因为我已经为 ConfigureServices 方法提供了联系人类型,所以 DI 能够解析它。我不能肯定地说我理解它为什么有效但我知道为了提供从一种类型到另一种类型的 link 你想直接请求它们作为 [=12= 中提供的类型].

实际上,您正在使用 GraphQL 来获取数据?你可以看一下 NReco.GraphQL 从盒子里做。无需为每个模式定义配置 classes/resolvers(只需在 JSON 文件中定义一次即可)。