本文介绍了在ASP.NET Core中实现GraphQL(用于.Net的GraphQL),为什么我的Query:ObjectGraphType类没有通过依赖项注入进行注册?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我已经设置了一个基本的Web Api,以使用ASP.Net Core演示GraphQL的用法。我已经按照教程进行了操作,感觉完全一样,但是却出现了一个我不明白的错误。

I've setup a basic Web Api demonstrate the use of GraphQL using ASP.Net Core. I've Followed a tutorial, what feels like exactly but am getting an error I don't understand.

我正在使用GraphQL for .NET v2.4.0

I'm using GraphQL for .NET v2.4.0

这是错误:

System.InvalidOperationException: No service for type 'Land.GraphQL.Queries.LandQuery' has been registered.
  at at Microsoft.Extensions.DependencyInjection.ServiceProviderServiceExtensions.GetRequiredService(IServiceProvider provider, Type serviceType)
  at at GraphQL.FuncDependencyResolver.Resolve(Type type)
  at at GraphQL.FuncDependencyResolver.Resolve[T]()
  at Land.GraphQL.LandSchema..ctor(IDependencyResolver resolver) in .../LandSchema.cs:11

我将不胜感激:)

这里是代码:

我创建了一个LandType:ObjectGraphType来定义类型:

I created a LandType:ObjectGraphType to define the Type:

    public class LandType : ObjectGraphType<Entities.Land>
    {
        public LandType(ILandDataAccess landDataAccess)
        {
            Name = "Land";

            Field(land => land.Id, type: typeof(IdGraphType)).Description("Land Id in LandApi context");
            Field(land => land.Apn)
                .Description(
                    "Assessor's Parcel Number (APN) is a unique number that is assigned to each tract of land in a county by the Tax Assessor.");
            Field(land => land.Address).Description("");
            Field(land => land.ZipCode).Description("");
            Field(land => land.City).Description("");
            Field(land => land.County).Description("");
            Field(land => land.State).Description("");
            Field(land => land.Country).Description("");
            Field(land => land.GisNumber).Description("");
            Field(land => land.AssessedValue).Description("");
            Field(land => land.LegalDescription).Description("");
            Field(land => land.Acreage, type: typeof(FloatGraphType)).Description("Acreage of Land");

        }
    }

我创建了一个LandQuery:ObjectGraphType来定义查询:

I created a LandQuery:ObjectGraphType to define the Query:

public class LandQuery : ObjectGraphType
    {
        public LandQuery(ILandDataAccess dataAccess)
        {
            Field<ListGraphType<LandType>>(
                "Land", 
                resolve: context => dataAccess.GetLandsAsync());
        }
    }

我创建了一个LandSchema:Schema来定义Schema:

I created a LandSchema:Schema to define the Schema:

public class LandSchema : Schema
    {
        public LandSchema(IDependencyResolver resolver) : base(resolver)
        {
            Query = resolver.Resolve<LandQuery>();
        }
    }

我在启动文件中添加了服务和中间件:

I added the service and middleware to the Startup file:

public void ConfigureServices(IServiceCollection services)
        {
            services.AddScoped<IDependencyResolver>(s => new FuncDependencyResolver(
                s.GetRequiredService));

            services.AddScoped<LandSchema>();

            services.AddGraphQL(o => { o.ExposeExceptions = true; })
                .AddGraphTypes(ServiceLifetime.Scoped);
        }

public void Configure(IApplicationBuilder app, IHostingEnvironment env)
        {
                app.UseGraphQL<LandSchema>();
        }






编辑:


多亏了@NateBarbettini和@TonyNgo的评论者,我才找到了答案。结果 .AddGraphTypes 仅搜索调用程序集。我的GraphTypes存储在引用的程序集中。传递引用的程序集解决了问题: .AddGraphTypes(typeof(LandSchema).Assembly,ServiceLifetime.Scoped);

Thanks to the commenters @NateBarbettini and @TonyNgo inspired me to find the answer. Turns out .AddGraphTypes only searches the calling assembly. My GraphTypes are stored in a referenced Assembly. passing the referenced assembly fixed the problem: .AddGraphTypes(typeof(LandSchema).Assembly, ServiceLifetime.Scoped);

推荐答案

GraphQL.NET要求您显式注册很多东西。快速解答:您需要注册 LandQuery

GraphQL.NET requires you to explicitly register a lot of things. Quick answer: you need to register LandQuery.

您有:

services.AddScoped<IDependencyResolver>(s => new FuncDependencyResolver(s.GetRequiredService));

IDependencyResolver 充当胶水在GraphQL.NET系统(需要请求许多服务类型)和ASP.NET Core的服务集合(其中包含服务类型)之间。

The IDependencyResolver acts as a "glue" between the GraphQL.NET system (which needs to request a lot of service types) and ASP.NET Core's service collection (which contains the service types).

对象图您给GraphQL.NET的代码以 LandSchema 开头,并已正确注册:

The object graph that you're giving to GraphQL.NET starts with LandSchema, which is correctly registered:

services.AddScoped<LandSchema>();

但是看看 LandSchema 在做什么!

Query = resolver.Resolve<LandQuery>();

此行向 IDependencyResolver 寻求 LandQuery 服务类型。您的 FuncDependencyResolver 指向ASP.NET Core服务集合,因此,如果注册了 LandQuery ,此操作将成功。不是,这就是为什么出现错误

This line asks the IDependencyResolver for a LandQuery service type. Your FuncDependencyResolver is pointing at the ASP.NET Core service collection, so this will succeed if LandQuery is registered. It isn't, which is why you are getting the error

要解决此问题,请在 ConfigureServices 中添加几行:

To fix it, add a few new lines to ConfigureServices:

services.AddScoped<LandQuery>();
services.AddScoped<LandType>();

任何类型或服务(包括 ILandDataAccess )其中一种GraphQL类型所必需的将需要在 ConfigureServices 中进行注册。如果您不想手动注册每个GraphQL.NET类型,请使用自动执行以下操作:从 GraphType 派生的寄存器类型:

Any type or service (including ILandDataAccess) required by one of the GraphQL types will need to be registered in ConfigureServices. If you don't want to hand-register every single GraphQL.NET type, use Scrutor to auto-register types that derive from GraphType:

// Add all classes that represent graph types
services.Scan(scan => scan
    .FromAssemblyOf<LandQuery>()
    .AddClasses(classes => classes.AssignableTo<GraphQL.Types.GraphType>())
        .AsSelf()
        .WithSingletonLifetime());

这篇关于在ASP.NET Core中实现GraphQL(用于.Net的GraphQL),为什么我的Query:ObjectGraphType类没有通过依赖项注入进行注册?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

11-02 13:29