From 12521577941087d978e0fa62b2528d0d1925e7e5 Mon Sep 17 00:00:00 2001 From: Michael Staib Date: Mon, 16 Dec 2019 22:59:39 +0100 Subject: [PATCH] Added support for generic object type extensions. (#1297) --- src/Core/Types.Tests/Types/EnumTypeTests.cs | 30 ++++ .../Types/ObjectTypeExtensionTests.cs | 70 +++++++- ...ring_Should_Not_Interfere_With_Scalar.snap | 15 ++ ...eExtension_DepricateField_With_Reason.snap | 14 -- ...tension_DepricateField_Without_Reason.snap | 14 -- ...jectTypeExtension_Execute_Infer_Field.snap | 8 + .../Definitions/ObjectTypeDefinition.cs | 16 +- .../Definitions/TypeDefinitionBase~1.cs | 2 +- .../Helpers/FieldDescriptorUtilities.cs | 22 ++- .../Descriptors/InterfaceTypeDescriptor.cs | 6 +- .../Types/Descriptors/ObjectTypeDescriptor.cs | 4 + .../Descriptors/ObjectTypeDescriptorBase~1.cs | 154 ++++++++++++++++++ .../Descriptors/ObjectTypeDescriptor~1.cs | 143 +--------------- .../ObjectTypeExtensionDescriptor~1.cs | 42 +++++ src/Core/Types/Types/ObjectTypeExtension.cs | 4 +- src/Core/Types/Types/ObjectTypeExtension~1.cs | 42 +++++ 16 files changed, 402 insertions(+), 184 deletions(-) create mode 100644 src/Core/Types.Tests/Types/__snapshots__/EnumTypeTests.EnumType_That_Is_Bound_To_String_Should_Not_Interfere_With_Scalar.snap delete mode 100644 src/Core/Types.Tests/Types/__snapshots__/ObjectTypeExtensionTests.ObjectTypeExtension_DepricateField_With_Reason.snap delete mode 100644 src/Core/Types.Tests/Types/__snapshots__/ObjectTypeExtensionTests.ObjectTypeExtension_DepricateField_Without_Reason.snap create mode 100644 src/Core/Types.Tests/Types/__snapshots__/ObjectTypeExtensionTests.ObjectTypeExtension_Execute_Infer_Field.snap create mode 100644 src/Core/Types/Types/Descriptors/ObjectTypeDescriptorBase~1.cs create mode 100644 src/Core/Types/Types/Descriptors/ObjectTypeExtensionDescriptor~1.cs create mode 100644 src/Core/Types/Types/ObjectTypeExtension~1.cs diff --git a/src/Core/Types.Tests/Types/EnumTypeTests.cs b/src/Core/Types.Tests/Types/EnumTypeTests.cs index 72ced9aa38d..a402b40789f 100644 --- a/src/Core/Types.Tests/Types/EnumTypeTests.cs +++ b/src/Core/Types.Tests/Types/EnumTypeTests.cs @@ -489,6 +489,16 @@ public void Deprecate_Fields_With_Deprecated_Attribute() schema.ToString().MatchSnapshot(); } + [Fact] + public void EnumType_That_Is_Bound_To_String_Should_Not_Interfere_With_Scalar() + { + SchemaBuilder.New() + .AddQueryType() + .Create() + .ToString() + .MatchSnapshot(); + } + public enum Foo { Bar1, @@ -511,5 +521,25 @@ public enum FooDeprecated [GraphQLDeprecated("Baz.")] Bar2 } + + public class SomeQueryType : ObjectType + { + protected override void Configure(IObjectTypeDescriptor descriptor) + { + descriptor.Name("Query"); + descriptor.Field("a").Type().Resolver("DEF"); + descriptor.Field("b").Type().Resolver("StringResolver"); + } + } + + public class SomeEnumType + : EnumType + { + protected override void Configure(IEnumTypeDescriptor descriptor) + { + descriptor.Name("Some"); + descriptor.Value("ABC").Name("DEF"); + } + } } } diff --git a/src/Core/Types.Tests/Types/ObjectTypeExtensionTests.cs b/src/Core/Types.Tests/Types/ObjectTypeExtensionTests.cs index 0031d8bf8ee..dcb7a094839 100644 --- a/src/Core/Types.Tests/Types/ObjectTypeExtensionTests.cs +++ b/src/Core/Types.Tests/Types/ObjectTypeExtensionTests.cs @@ -29,6 +29,57 @@ public void ObjectTypeExtension_AddField() Assert.True(type.Fields.ContainsField("test")); } + [Fact] + public void ObjectTypeExtension_Infer_Field() + { + // arrange + // act + ISchema schema = SchemaBuilder.New() + .AddQueryType() + .AddType() + .Create(); + + // assert + ObjectType type = schema.GetType("Foo"); + Assert.True(type.Fields.ContainsField("test")); + } + + [Fact] + public void ObjectTypeExtension_Declare_Field() + { + // arrange + // act + ISchema schema = SchemaBuilder.New() + .AddQueryType() + .AddType(new ObjectTypeExtension(d => + { + d.Name("Foo"); + d.Field(t => t.Test).Type(); + })) + .Create(); + + // assert + ObjectType type = schema.GetType("Foo"); + Assert.True(type.Fields.ContainsField("test")); + Assert.IsType(type.Fields["test"].Type); + } + + [Fact] + public async Task ObjectTypeExtension_Execute_Infer_Field() + { + // arrange + // act + IQueryExecutor executor = SchemaBuilder.New() + .AddQueryType() + .AddType() + .Create() + .MakeExecutable(); + + // assert + IExecutionResult result = await executor.ExecuteAsync("{ test }"); + result.MatchSnapshot(); + } + [Fact] public void ObjectTypeExtension_OverrideResolver() { @@ -124,7 +175,7 @@ public void ObjectTypeExtension_DeprecateField_Obsolete() } [Fact] - public void ObjectTypeExtension_DepricateField_With_Reason() + public void ObjectTypeExtension_DeprecateField_With_Reason() { // arrange FieldResolverDelegate resolver = @@ -148,7 +199,7 @@ public void ObjectTypeExtension_DepricateField_With_Reason() } [Fact] - public void ObjectTypeExtension_DepricateField_Without_Reason() + public void ObjectTypeExtension_DeprecateField_Without_Reason() { // arrange FieldResolverDelegate resolver = @@ -484,6 +535,16 @@ protected override void Configure( } } + public class GenericFooTypeExtension + : ObjectTypeExtension + { + protected override void Configure( + IObjectTypeDescriptor descriptor) + { + descriptor.Name("Foo"); + } + } + public class Foo { public string Description { get; } = "hello"; @@ -494,6 +555,11 @@ public string GetName(string a) } } + public class FooExtension + { + public string Test { get; set; } = "Test123"; + } + public class FooResolver { public string GetName2() diff --git a/src/Core/Types.Tests/Types/__snapshots__/EnumTypeTests.EnumType_That_Is_Bound_To_String_Should_Not_Interfere_With_Scalar.snap b/src/Core/Types.Tests/Types/__snapshots__/EnumTypeTests.EnumType_That_Is_Bound_To_String_Should_Not_Interfere_With_Scalar.snap new file mode 100644 index 00000000000..e3df1abd073 --- /dev/null +++ b/src/Core/Types.Tests/Types/__snapshots__/EnumTypeTests.EnumType_That_Is_Bound_To_String_Should_Not_Interfere_With_Scalar.snap @@ -0,0 +1,15 @@ +schema { + query: Query +} + +type Query { + a: Some + b: String +} + +enum Some { + DEF +} + +"The `String` scalar type represents textual data, represented as UTF-8 character sequences. The String type is most often used by GraphQL to represent free-form human-readable text." +scalar String diff --git a/src/Core/Types.Tests/Types/__snapshots__/ObjectTypeExtensionTests.ObjectTypeExtension_DepricateField_With_Reason.snap b/src/Core/Types.Tests/Types/__snapshots__/ObjectTypeExtensionTests.ObjectTypeExtension_DepricateField_With_Reason.snap deleted file mode 100644 index c0c194c4331..00000000000 --- a/src/Core/Types.Tests/Types/__snapshots__/ObjectTypeExtensionTests.ObjectTypeExtension_DepricateField_With_Reason.snap +++ /dev/null @@ -1,14 +0,0 @@ -schema { - query: Foo -} - -type Foo { - description: String @deprecated(reason: "Foo") - name(a: String): String -} - -"The @deprecated directive is used within the type system definition language to indicate deprecated portions of a GraphQL service’s schema,such as deprecated fields on a type or deprecated enum values." -directive @deprecated("Deprecations include a reason for why it is deprecated, which is formatted using Markdown syntax (as specified by CommonMark)." reason: String = "No longer supported") on FIELD_DEFINITION | ENUM_VALUE - -"The `String` scalar type represents textual data, represented as UTF-8 character sequences. The String type is most often used by GraphQL to represent free-form human-readable text." -scalar String diff --git a/src/Core/Types.Tests/Types/__snapshots__/ObjectTypeExtensionTests.ObjectTypeExtension_DepricateField_Without_Reason.snap b/src/Core/Types.Tests/Types/__snapshots__/ObjectTypeExtensionTests.ObjectTypeExtension_DepricateField_Without_Reason.snap deleted file mode 100644 index 2519c6d470f..00000000000 --- a/src/Core/Types.Tests/Types/__snapshots__/ObjectTypeExtensionTests.ObjectTypeExtension_DepricateField_Without_Reason.snap +++ /dev/null @@ -1,14 +0,0 @@ -schema { - query: Foo -} - -type Foo { - description: String @deprecated - name(a: String): String -} - -"The @deprecated directive is used within the type system definition language to indicate deprecated portions of a GraphQL service’s schema,such as deprecated fields on a type or deprecated enum values." -directive @deprecated("Deprecations include a reason for why it is deprecated, which is formatted using Markdown syntax (as specified by CommonMark)." reason: String = "No longer supported") on FIELD_DEFINITION | ENUM_VALUE - -"The `String` scalar type represents textual data, represented as UTF-8 character sequences. The String type is most often used by GraphQL to represent free-form human-readable text." -scalar String diff --git a/src/Core/Types.Tests/Types/__snapshots__/ObjectTypeExtensionTests.ObjectTypeExtension_Execute_Infer_Field.snap b/src/Core/Types.Tests/Types/__snapshots__/ObjectTypeExtensionTests.ObjectTypeExtension_Execute_Infer_Field.snap new file mode 100644 index 00000000000..04e31205e59 --- /dev/null +++ b/src/Core/Types.Tests/Types/__snapshots__/ObjectTypeExtensionTests.ObjectTypeExtension_Execute_Infer_Field.snap @@ -0,0 +1,8 @@ +{ + "Data": { + "test": "Test123" + }, + "Extensions": {}, + "Errors": [], + "ContextData": {} +} diff --git a/src/Core/Types/Types/Descriptors/Definitions/ObjectTypeDefinition.cs b/src/Core/Types/Types/Descriptors/Definitions/ObjectTypeDefinition.cs index d789f7d3195..2a2f99ef8f6 100644 --- a/src/Core/Types/Types/Descriptors/Definitions/ObjectTypeDefinition.cs +++ b/src/Core/Types/Types/Descriptors/Definitions/ObjectTypeDefinition.cs @@ -1,4 +1,4 @@ -using System.Collections; +using System; using System.Collections.Generic; using HotChocolate.Language; @@ -7,13 +7,23 @@ namespace HotChocolate.Types.Descriptors.Definitions public class ObjectTypeDefinition : TypeDefinitionBase { + public override Type ClrType + { + get => base.ClrType; + set + { + base.ClrType = value; + FieldBindingType = value; + } + } + + public Type FieldBindingType { get; set; } + public IsOfType IsOfType { get; set; } public ICollection Interfaces { get; } = new List(); - public BindingBehavior FieldBindingBehavior { get; set; } - public IBindableList Fields { get; } = new BindableList(); diff --git a/src/Core/Types/Types/Descriptors/Definitions/TypeDefinitionBase~1.cs b/src/Core/Types/Types/Descriptors/Definitions/TypeDefinitionBase~1.cs index 58e06f33557..4c939402a3b 100644 --- a/src/Core/Types/Types/Descriptors/Definitions/TypeDefinitionBase~1.cs +++ b/src/Core/Types/Types/Descriptors/Definitions/TypeDefinitionBase~1.cs @@ -17,7 +17,7 @@ protected TypeDefinitionBase() { } /// /// Gets or sets the .net type representation of this type. /// - public Type ClrType + public virtual Type ClrType { get => _clrType; set diff --git a/src/Core/Types/Types/Descriptors/Helpers/FieldDescriptorUtilities.cs b/src/Core/Types/Types/Descriptors/Helpers/FieldDescriptorUtilities.cs index 8058a3c3d74..9b9a2db0b9d 100644 --- a/src/Core/Types/Types/Descriptors/Helpers/FieldDescriptorUtilities.cs +++ b/src/Core/Types/Types/Descriptors/Helpers/FieldDescriptorUtilities.cs @@ -41,10 +41,28 @@ public static void AddImplicitFields( where TMember : MemberInfo where TField : FieldDefinitionBase { - if (descriptor.ClrType != typeof(object)) + AddImplicitFields( + descriptor, + descriptor.ClrType, + createdFieldDefinition, + fields, + handledMembers); + } + + public static void AddImplicitFields( + TDescriptor descriptor, + Type fieldBindingType, + Func createdFieldDefinition, + IDictionary fields, + ISet handledMembers) + where TDescriptor : IHasDescriptorContext + where TMember : MemberInfo + where TField : FieldDefinitionBase + { + if (fieldBindingType != typeof(object)) { foreach (TMember member in descriptor.Context.Inspector - .GetMembers(descriptor.ClrType) + .GetMembers(fieldBindingType) .OfType()) { TField fieldDefinition = createdFieldDefinition(member); diff --git a/src/Core/Types/Types/Descriptors/InterfaceTypeDescriptor.cs b/src/Core/Types/Types/Descriptors/InterfaceTypeDescriptor.cs index 36733f18db7..519d2c19172 100644 --- a/src/Core/Types/Types/Descriptors/InterfaceTypeDescriptor.cs +++ b/src/Core/Types/Types/Descriptors/InterfaceTypeDescriptor.cs @@ -22,10 +22,8 @@ protected InterfaceTypeDescriptor( } Definition.ClrType = clrType; - Definition.Name = - context.Naming.GetTypeName(clrType, TypeKind.Interface); - Definition.Description = - context.Naming.GetTypeDescription(clrType, TypeKind.Interface); + Definition.Name = context.Naming.GetTypeName(clrType, TypeKind.Interface); + Definition.Description = context.Naming.GetTypeDescription(clrType, TypeKind.Interface); } protected InterfaceTypeDescriptor( diff --git a/src/Core/Types/Types/Descriptors/ObjectTypeDescriptor.cs b/src/Core/Types/Types/Descriptors/ObjectTypeDescriptor.cs index f5ccd064d83..4b7f42e416d 100644 --- a/src/Core/Types/Types/Descriptors/ObjectTypeDescriptor.cs +++ b/src/Core/Types/Types/Descriptors/ObjectTypeDescriptor.cs @@ -309,6 +309,10 @@ public static ObjectTypeDescriptor New( IDescriptorContext context) => new ObjectTypeDescriptor(context); + public static ObjectTypeExtensionDescriptor NewExtension( + IDescriptorContext context) => + new ObjectTypeExtensionDescriptor(context); + public static ObjectTypeDescriptor FromSchemaType( IDescriptorContext context, Type schemaType) diff --git a/src/Core/Types/Types/Descriptors/ObjectTypeDescriptorBase~1.cs b/src/Core/Types/Types/Descriptors/ObjectTypeDescriptorBase~1.cs new file mode 100644 index 00000000000..5a193d769cf --- /dev/null +++ b/src/Core/Types/Types/Descriptors/ObjectTypeDescriptorBase~1.cs @@ -0,0 +1,154 @@ +using System; +using System.Collections.Generic; +using System.Linq.Expressions; +using System.Reflection; +using HotChocolate.Language; +using HotChocolate.Types.Descriptors.Definitions; + +namespace HotChocolate.Types.Descriptors +{ + public class ObjectTypeDescriptorBase + : ObjectTypeDescriptor + , IObjectTypeDescriptor + , IHasClrType + { + public ObjectTypeDescriptorBase(IDescriptorContext context, Type clrType) + : base(context, clrType) + { + } + + public ObjectTypeDescriptorBase(IDescriptorContext context) + : base(context) + { + } + + Type IHasClrType.ClrType => Definition.ClrType; + + protected override void OnCompleteFields( + IDictionary fields, + ISet handledMembers) + { + if (Definition.Fields.IsImplicitBinding()) + { + FieldDescriptorUtilities.AddImplicitFields( + this, + Definition.FieldBindingType, + p => + { + ObjectFieldDescriptor descriptor = ObjectFieldDescriptor.New(Context, p); + Fields.Add(descriptor); + return descriptor.CreateDefinition(); + }, + fields, + handledMembers); + } + + base.OnCompleteFields(fields, handledMembers); + } + + public new IObjectTypeDescriptor Name(NameString value) + { + base.Name(value); + return this; + } + + public new IObjectTypeDescriptor Description( + string value) + { + base.Description(value); + return this; + } + + public IObjectTypeDescriptor BindFields( + BindingBehavior behavior) + { + Definition.Fields.BindingBehavior = behavior; + return this; + } + + public IObjectTypeDescriptor BindFieldsExplicitly() => + BindFields(BindingBehavior.Explicit); + + public IObjectTypeDescriptor BindFieldsImplicitly() => + BindFields(BindingBehavior.Implicit); + + public new IObjectTypeDescriptor Interface() + where TInterface : InterfaceType + { + base.Interface(); + return this; + } + + public new IObjectTypeDescriptor Interface( + TInterface type) + where TInterface : InterfaceType + { + base.Interface(type); + return this; + } + + public new IObjectTypeDescriptor Implements() + where TInterface : InterfaceType => + Interface(); + + public new IObjectTypeDescriptor Interface(NamedTypeNode type) + { + base.Interface(type); + return this; + } + + public new IObjectTypeDescriptor Implements(TInterface type) + where TInterface : InterfaceType => + Interface(type); + + public new IObjectTypeDescriptor Implements(NamedTypeNode type) => + Interface(type); + + public new IObjectTypeDescriptor Include() + { + base.Include(); + return this; + } + + public new IObjectTypeDescriptor IsOfType(IsOfType isOfType) + { + base.IsOfType(isOfType); + return this; + } + + public IObjectFieldDescriptor Field( + Expression> propertyOrMethod) + { + return base.Field(propertyOrMethod); + } + + public IObjectFieldDescriptor Field( + Expression> propertyOrMethod) + { + return base.Field(propertyOrMethod); + } + + public new IObjectTypeDescriptor Directive( + TDirective directiveInstance) + where TDirective : class + { + base.Directive(directiveInstance); + return this; + } + + public new IObjectTypeDescriptor Directive() + where TDirective : class, new() + { + base.Directive(new TDirective()); + return this; + } + + public new IObjectTypeDescriptor Directive( + NameString name, + params ArgumentNode[] arguments) + { + base.Directive(name, arguments); + return this; + } + } +} diff --git a/src/Core/Types/Types/Descriptors/ObjectTypeDescriptor~1.cs b/src/Core/Types/Types/Descriptors/ObjectTypeDescriptor~1.cs index d93a19f2864..9782d47b7f3 100644 --- a/src/Core/Types/Types/Descriptors/ObjectTypeDescriptor~1.cs +++ b/src/Core/Types/Types/Descriptors/ObjectTypeDescriptor~1.cs @@ -1,151 +1,12 @@ -using System; -using System.Collections.Generic; -using System.Linq.Expressions; -using System.Reflection; -using HotChocolate.Language; -using HotChocolate.Types.Descriptors.Definitions; - namespace HotChocolate.Types.Descriptors { public class ObjectTypeDescriptor - : ObjectTypeDescriptor - , IObjectTypeDescriptor - , IHasClrType + : ObjectTypeDescriptorBase { public ObjectTypeDescriptor(IDescriptorContext context) : base(context, typeof(T)) { - Definition.Fields.BindingBehavior = - context.Options.DefaultBindingBehavior; - } - - Type IHasClrType.ClrType => Definition.ClrType; - - protected override void OnCompleteFields( - IDictionary fields, - ISet handledMembers) - { - if (Definition.Fields.IsImplicitBinding()) - { - FieldDescriptorUtilities.AddImplicitFields( - this, - p => - { - // how to fix the field declaration issue - ObjectFieldDescriptor descriptor = ObjectFieldDescriptor.New(Context, p); - Fields.Add(descriptor); - return descriptor.CreateDefinition(); - }, - fields, - handledMembers); - } - - base.OnCompleteFields(fields, handledMembers); - } - - public new IObjectTypeDescriptor Name(NameString value) - { - base.Name(value); - return this; - } - - public new IObjectTypeDescriptor Description( - string value) - { - base.Description(value); - return this; - } - - public IObjectTypeDescriptor BindFields( - BindingBehavior behavior) - { - Definition.Fields.BindingBehavior = behavior; - return this; - } - - public IObjectTypeDescriptor BindFieldsExplicitly() => - BindFields(BindingBehavior.Explicit); - - public IObjectTypeDescriptor BindFieldsImplicitly() => - BindFields(BindingBehavior.Implicit); - - public new IObjectTypeDescriptor Interface() - where TInterface : InterfaceType - { - base.Interface(); - return this; - } - - public new IObjectTypeDescriptor Interface( - TInterface type) - where TInterface : InterfaceType - { - base.Interface(type); - return this; - } - - public new IObjectTypeDescriptor Implements() - where TInterface : InterfaceType => - Interface(); - - public new IObjectTypeDescriptor Interface(NamedTypeNode type) - { - base.Interface(type); - return this; - } - - public new IObjectTypeDescriptor Implements(TInterface type) - where TInterface : InterfaceType => - Interface(type); - - public new IObjectTypeDescriptor Implements(NamedTypeNode type) => - Interface(type); - - public new IObjectTypeDescriptor Include() - { - base.Include(); - return this; - } - - public new IObjectTypeDescriptor IsOfType(IsOfType isOfType) - { - base.IsOfType(isOfType); - return this; - } - - public IObjectFieldDescriptor Field( - Expression> propertyOrMethod) - { - return base.Field(propertyOrMethod); - } - - public IObjectFieldDescriptor Field( - Expression> propertyOrMethod) - { - return base.Field(propertyOrMethod); - } - - public new IObjectTypeDescriptor Directive( - TDirective directiveInstance) - where TDirective : class - { - base.Directive(directiveInstance); - return this; - } - - public new IObjectTypeDescriptor Directive() - where TDirective : class, new() - { - base.Directive(new TDirective()); - return this; - } - - public new IObjectTypeDescriptor Directive( - NameString name, - params ArgumentNode[] arguments) - { - base.Directive(name, arguments); - return this; + Definition.Fields.BindingBehavior = context.Options.DefaultBindingBehavior; } } } diff --git a/src/Core/Types/Types/Descriptors/ObjectTypeExtensionDescriptor~1.cs b/src/Core/Types/Types/Descriptors/ObjectTypeExtensionDescriptor~1.cs new file mode 100644 index 00000000000..a3b272a2c87 --- /dev/null +++ b/src/Core/Types/Types/Descriptors/ObjectTypeExtensionDescriptor~1.cs @@ -0,0 +1,42 @@ +using System.Collections.Generic; +using System.Reflection; +using HotChocolate.Types.Descriptors.Definitions; + +namespace HotChocolate.Types.Descriptors +{ + public class ObjectTypeExtensionDescriptor + : ObjectTypeDescriptorBase + { + public ObjectTypeExtensionDescriptor(IDescriptorContext context) + : base(context) + { + Definition.Name = context.Naming.GetTypeName(typeof(T), TypeKind.Object); + Definition.Description = context.Naming.GetTypeDescription(typeof(T), TypeKind.Object); + Definition.Fields.BindingBehavior = context.Options.DefaultBindingBehavior; + Definition.FieldBindingType = typeof(T); + } + + protected override void OnCompleteFields( + IDictionary fields, + ISet handledMembers) + { + if (Definition.Fields.IsImplicitBinding()) + { + FieldDescriptorUtilities.AddImplicitFields( + this, + Definition.FieldBindingType, + p => + { + ObjectFieldDescriptor descriptor = + ObjectFieldDescriptor.New(Context, p, Definition.FieldBindingType); + Fields.Add(descriptor); + return descriptor.CreateDefinition(); + }, + fields, + handledMembers); + } + + base.OnCompleteFields(fields, handledMembers); + } + } +} diff --git a/src/Core/Types/Types/ObjectTypeExtension.cs b/src/Core/Types/Types/ObjectTypeExtension.cs index 8f0aa6abf78..f5b14b7107a 100644 --- a/src/Core/Types/Types/ObjectTypeExtension.cs +++ b/src/Core/Types/Types/ObjectTypeExtension.cs @@ -1,10 +1,8 @@ -using System.Collections.Generic; using System; using HotChocolate.Configuration; +using HotChocolate.Properties; using HotChocolate.Types.Descriptors; using HotChocolate.Types.Descriptors.Definitions; -using System.Linq; -using HotChocolate.Properties; namespace HotChocolate.Types { diff --git a/src/Core/Types/Types/ObjectTypeExtension~1.cs b/src/Core/Types/Types/ObjectTypeExtension~1.cs new file mode 100644 index 00000000000..695cabb059e --- /dev/null +++ b/src/Core/Types/Types/ObjectTypeExtension~1.cs @@ -0,0 +1,42 @@ +using System; +using HotChocolate.Configuration; +using HotChocolate.Types.Descriptors; +using HotChocolate.Types.Descriptors.Definitions; + +namespace HotChocolate.Types +{ + public class ObjectTypeExtension + : ObjectTypeExtension + { + private readonly Action> _configure; + + public ObjectTypeExtension() + { + _configure = Configure; + } + + public ObjectTypeExtension(Action> configure) + { + _configure = configure + ?? throw new ArgumentNullException(nameof(configure)); + } + + protected override ObjectTypeDefinition CreateDefinition( + IInitializationContext context) + { + var descriptor = ObjectTypeDescriptor.NewExtension( + context.DescriptorContext); + _configure(descriptor); + return descriptor.CreateDefinition(); + } + + protected virtual void Configure(IObjectTypeDescriptor descriptor) + { + } + + protected sealed override void Configure(IObjectTypeDescriptor descriptor) + { + throw new NotSupportedException(); + } + } +}