首页 > 解决方案 > .net 核心中的 Web Api 找不到 GraphQL 所需的服务

问题描述

我有一个正在处理的 api,但我一直遇到这个错误:

InnerException
{“未找到类型 GraphQL.Types.InterfaceGraphType1[CardSortApiV3.Domain.DTO.ContactDTO] 所需的服务”} 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>();
}

联系查询.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;
            });
    }
}

项目查询.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);
            });
    }
}

主查询.cs

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

架构.cs

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

在过去的 4 个小时里,我一直在研究和寻找答案,但没有任何效果。一切正常,直到我尝试添加链接ContactProject.

任何帮助将不胜感激。

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

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");
    }
}

项目类型.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");
    }
}

标签: c#graphql

解决方案


我实际上找到了答案,尽管它一开始似乎不起作用。

启动.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方法提供了 Contact 类型,所以 DI 能够解决它。我不能肯定地说我理解它为什么起作用,但我知道为了提供从一种类型到另一种类型的链接,您希望直接请求它们作为ConfigureServices.


推荐阅读