#c# #graphql
Вопрос:
У меня есть api, над которым я работаю, и я продолжаю сталкиваться с этой ошибкой:
InnerException
{«Требуется служба для типа GraphQL.Types.Тип интерфейса1[CardSortApiV3.Domain.DTO.ContactDTO] не найден»} Система.Исключение {Система.Исключение недействительной операции}
У меня есть следующий код в их соответствующих файлах: 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
на a 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");
}
}
Тип проекта.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");
}
}
Комментарии:
1. Существует ли несколько определений
ContactDTO
? Возможно, добавил не тот?2. @JHBonarius Нет, есть только одно определение для
ContactDTO
3. Для справки, он ломается при последнем
Field
звонке вProjectType
Ответ №1:
Я действительно нашел ответ, хотя поначалу казалось, что это не сработает.
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 смог его разрешить. Я не могу с уверенностью сказать, что понимаю, почему это работает, но я знаю, что для того, чтобы предоставить ссылку от одного типа к другому, вы хотите запросить их напрямую как типы, которые указаны в ConfigureServices
.
Ответ №2:
На самом деле, вы используете GraphQL для извлечения данных? вы можете посмотреть NReco.GraphQL, чтобы сделать это из коробки. Нет необходимости настраивать классы/распознаватели для каждого определения схемы (достаточно просто определить его один раз в файле JSON).