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的方式告知继承关系,按理抽象类和子类的继承关系也是可以和接口一样知道的,希望下一版中更智能一些。
想要更快更方便的了解相关知识,可以关注微信公众号
****欢迎关注我的asp.net core系统课程****
《asp.net core精要讲解》 https://ke.qq.com/course/265696
《asp.net core 3.0》 https://ke.qq.com/course/437517
《asp.net core项目实战》 https://ke.qq.com/course/291868
《基于.net core微服务》 https://ke.qq.com/course/299524
《asp.net core精要讲解》 https://ke.qq.com/course/265696
《asp.net core 3.0》 https://ke.qq.com/course/437517
《asp.net core项目实战》 https://ke.qq.com/course/291868
《基于.net core微服务》 https://ke.qq.com/course/299524