ChilliCream / graphql-platform

Welcome to the home of the Hot Chocolate GraphQL server for .NET, the Strawberry Shake GraphQL client for .NET and Banana Cake Pop the awesome Monaco based GraphQL IDE.
https://chillicream.com
MIT License
5.24k stars 744 forks source link

InterfaceType in query added twice #6589

Open batbeer opened 1 year ago

batbeer commented 1 year ago

Is there an existing issue for this?

Product

Hot Chocolate

Describe the bug

it tries to add the InterfaceType both from the query and the type itself, causing hotchocolate to get an error:

The name Test was already registered by another type. (HotChocolate.Types.ObjectType)

Steps to reproduce

https://github.com/glen-84/hc-6589 (.NET 8, HC 13.8.1)

  1. Define abstract class
public abstract class Test
{
    public string Name { get; set; }
}

public class TestText : Test
{
    public string Text { get; set; }
}

public class TestNumber : Test
{
    public decimal Number { get; set; }
}
public class TestType : InterfaceType<Test>
{
    protected override void Configure(IInterfaceTypeDescriptor<Test> descriptor)
    {
        descriptor.BindFieldsExplicitly();

        descriptor.Field(f => f.Name);
    }
}

public class TestTextType : ObjectType<TestText>
{
    protected override void Configure(IObjectTypeDescriptor<TestText> descriptor)
    {
        descriptor.BindFieldsExplicitly();

        descriptor.Name("TestText");

        descriptor.Implements<TestType>();

        descriptor
            .Field(f => f.Name);

        descriptor
            .Field(f => f.Text);
    }
}

public class TestNumberType : ObjectType<TestNumber>
{
    protected override void Configure(IObjectTypeDescriptor<TestNumber> descriptor)
    {
        descriptor.BindFieldsExplicitly();

        descriptor.Name("TestNumber");

        descriptor.Implements<TestType>();

        descriptor
            .Field(f => f.Name);

        descriptor
            .Field(f => f.Number);
    }
}
  1. Use in query
[ExtendObjectType(OperationTypeNames.Query)]
public class TestQuery
{
    [UseDbContext(typeof(DatabaseContext))]
    [GraphQLDescription("Get Test")]
    [UsePaging(IncludeTotalCount = true, DefaultPageSize = 20, MaxPageSize = 50)]
    [UseProjection]
    [UseSorting(typeof(TestSortInput))]
    [UseFiltering(typeof(TestFilterInput))]
    public IQueryable<Test> GetTests(DatabaseContext databaseContext)
    {
        //here the abstract class is added as an objectType, then causing the error
        //return databaseContext.Tests
    }
}

public class TestFilterInput : FilterInputType<Test>
{
    protected override void Configure(IFilterInputTypeDescriptor<Test> descriptor)
    {
        descriptor.BindFieldsExplicitly();

        descriptor.Field(f => f.Name);
    }
}

public class TestSortInput : SortInputType<Test>
{
    protected override void Configure(ISortInputTypeDescriptor<Test> descriptor)
    {
        descriptor.BindFieldsExplicitly();

        descriptor.Field(f => f.Name);
    }
}
  1. run program

result in the error: The name Test was already registered by another type. (HotChocolate.Types.ObjectType)

Relevant log output

The name `Test` was already registered by another type. (HotChocolate.Types.ObjectType<Path.To.Class.Test>)

Additional Context?

No response

Version

13.5.1

PascalSenn commented 1 year ago

Do you register the InterfacetTYpe on the schema builder with AddType<TestType> ?

batbeer commented 1 year ago

yes it is registered, the issue is that it tries to register it again as a objectType when used in the query. public IQueryable<Test> GetTests(DatabaseContext databaseContext)

Edit: updated it so it looks like actual code

PascalSenn commented 1 year ago

Can you provide a minimal reproduction of this issue in a Github repository? Best start with dotnet new graphql

madiganz commented 1 year ago

@batbeer try to add UsePaging(typeof(TestType)). I had the same problem as you and just figured it out. I believe it's do to something in the UsePaging logic not able to find the interface type correctly.

batbeer commented 1 year ago

@madiganz Thanks! this works 👍