Fork me on GitHub

GraphQL:Interface和子类怎么查?

 

   向对象的继承,是个好东西;GraphQL也是个好东西;怎么能有机的结合起来,发挥彼此的能量?Hot Chocklate实现了.net和GraphQL的灵活组合,一起来看看,这是接口和子类的实现:

  class Program
    {
        static void Main(string[] args)
        {
            InterfaceDemo.Run();
        }
    }
    public class InterfaceDemo
    {
        public static void Run()
        {
            var schema = SchemaBuilder.New()
                .AddQueryType<Query>()
                .AddType<AFormat>()             
                .AddType<BFormat>()                
                .AddProjections()
                .Create();

            var executor = schema.MakeExecutable();
            Console.WriteLine(executor.Execute(@"
{
    formats
    {
        __typename,
        name,        
        ... on AFormat{
            a1,
            a2
        },
        ... on BFormat{
            b1,
            b2
        }
    } 
}").ToJson());
        }
    }
    public class Query
    {
        public IFormat[] GetFormats()
        {
            return new IFormat[]
            {
                    new AFormat{
                         Name="A",
                         A1="A1",
                         A2="A2"
                    },
                    new BFormat{
                       Name="B",
                       B1="B1",
                       B2="B2"
                    }
            };
        }
    }

    [GraphQLName("Format")]
    public interface IFormat
    {
        string Name { get; set; }
    }

    public class AFormat : IFormat
    {
        public string Name { get; set; }
        public string A1 { get; set; }
        public string A2 { get; set; }
    }

    public class BFormat : IFormat
    {
        public string Name { get; set; }
        public string B1 { get; set; }
        public string B2 { get; set; }
    }
 

接口结果:

{
  "data": {
    "formats": [
      {
        "__typename": "AFormat",
        "name": "A",
        "a1": "A1",
        "a2": "A2"
      },
      {
        "__typename": "BFormat",
        "name": "B",
        "b1": "B1",
        "b2": "B2"
      }
    ]
  }
}

抽象类的实现怎么样呢?

抽象类第一版:

 class Program
    {
        static void Main(string[] args)
        {
            InterfaceDemo.Run();
        }
    }
    public class InterfaceDemo
    {

        public static void Run()
        {
            var schema = SchemaBuilder.New()
                .AddQueryType<Query>()
                .AddType<AFormat>()             
                .AddType<BFormat>()                
                .AddProjections()
                .Create();

            var executor = schema.MakeExecutable();
            Console.WriteLine(executor.Execute(@"
{
    formats
    {
        __typename,
        name,        
        ... on AFormat{
            a1,
            a2
        },
        ... on BFormat{
            b1,
            b2
        }
    } 
}").ToJson());
        }
    }

    public class Query
    {
        public Format[] GetFormats()
        {
            return new Format[]
            {
                    new AFormat{
                         Name="A",
                         A1="A1",
                         A2="A2"
                    },
                    new BFormat{
                       Name="B",
                       B1="B1",
                       B2="B2"
                    }
            };
        }
    }
    [InterfaceType]
    public abstract class Format
    {
        public string Name { get; set; }
    }
    public class AFormat : Format
    {
        public string A1 { get; set; }
        public string A2 { get; set; }
    }
    public class BFormat : Format
    {
        public string B1 { get; set; }
        public string B2 { get; set; }
    }

  抽象类第一版结果,报错,说是没有实现抽象类Format,看来抽象类并不是我想象的使用方式,草率了。

Unhandled exception. HotChocolate.SchemaException: For more details look at the `Errors` property.

1. There is no object type implementing interface `Format`. (HotChocolate.Types.InterfaceType<GraphQLDemo005.Format>)

   at HotChocolate.Configuration.TypeInitializer.Initialize(Func`1 schemaResolver, IReadOnlySchemaOptions options)
   at HotChocolate.SchemaBuilder.Setup.InitializeTypes(SchemaBuilder builder, DescriptorContext context, IBindingLookup bindingLookup, IReadOnlyList`1 types, LazySchema lazySchema)
   at HotChocolate.SchemaBuilder.Setup.Create(SchemaBuilder builder)
   at HotChocolate.SchemaBuilder.Create()
   at HotChocolate.SchemaBuilder.HotChocolate.ISchemaBuilder.Create()
   at GraphQLDemo005.InterfaceDemo.Run() in C:\MyFile\Source\Repos\Asp.NetCoreExperiment\Asp.NetCoreExperiment\GraphQL\GraphQLDemo005\Program.cs:line 33
   at GraphQLDemo005.Program.Main(String[] args) in C:\MyFile\Source\Repos\Asp.NetCoreExperiment\Asp.NetCoreExperiment\GraphQL\GraphQLDemo005\Program.cs:line 25

抽象类第二版

 class Program
    {
        static void Main(string[] args)
        {
            InterfaceDemo.Run();
        }
    }
    public class InterfaceDemo
    {
        public static void Run()
        {
            var schema = SchemaBuilder.New()
                .AddQueryType<Query>()
                .AddType<AFormatType>()
                .AddType<BFormatType>()
                .AddProjections()
                .Create();
            var executor = schema.MakeExecutable();
            Console.WriteLine(executor.Execute(@"
{
    formats
    {
        __typename,
        name,        
        ... on AFormat{
            a1,
            a2
        },
        ... on BFormat{
            b1,
            b2
        }
    } 
}").ToJson());
        }
    }
   
   public class Query
    {
        public Format[] GetFormats()
        {
            return new Format[]
            {
                    new AFormat{
                         Name="A",
                         A1="A1",
                         A2="A2"
                    },
                    new BFormat{
                       Name="B",
                       B1="B1",
                       B2="B2"
                    }
            };
        }
    }

    public abstract class Format
    {
        public abstract string Name { get; set; }
    }
    public class AFormat : Format
    {
        public override string Name { get; set; }
        public string A1 { get; set; }
        public string A2 { get; set; }
    }
    public class BFormat : Format
    {
        public override string Name { get; set; }
        public string B1 { get; set; }
        public string B2 { get; set; }
    }
    public class FormatType : InterfaceType<Format>
    {
        protected override void Configure(IInterfaceTypeDescriptor<Format> descriptor)
        {
            base.Configure(descriptor);
        }
    }
    public class AFormatType : ObjectType<AFormat>
    {
        protected override void Configure(IObjectTypeDescriptor<AFormat> descriptor)
        {
            descriptor.Implements<FormatType>();
        }
    }
    public class BFormatType : ObjectType<BFormat>
    {
        protected override void Configure(IObjectTypeDescriptor<BFormat> descriptor)
        {
            descriptor.Implements<FormatType>();
        }
    }

抽象类第二版结果:

{
  "data": {
    "formats": [
      {
        "__typename": "AFormat",
        "name": "A",
        "a1": "A1",
        "a2": "A2"
      },
      {
        "__typename": "BFormat",
        "name": "B",
        "b1": "B1",
        "b2": "B2"
      }
    ]
  }
}

  抽象类第二版就是用指定***Type的方式告知继承关系,按理抽象类和子类的继承关系也是可以和接口一样知道的,希望下一版中更智能一些。

 

  想要更快更方便的了解相关知识,可以关注微信公众号 
 

 

 

posted @ 2022-02-03 13:47  桂素伟  阅读(65)  评论(1编辑  收藏  举报