向对象的继承,是个好东西;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的方式告知继承关系,按理抽象类和子类的继承关系也是可以和接口一样知道的,希望下一版中更智能一些。
想要更快更方便的了解相关知识,可以关注微信公众号