conventions icon indicating copy to clipboard operation
conventions copied to clipboard

Weird behavior that make ignoring specific field harder on deriving fields

Open vcup opened this issue 1 year ago • 4 comments

Hello theres.

I have some type definition like below:

interface ISomeInterface
{
    public SomeOutputType SomeProperty { get; set; }
}
[InputType] // actually is setted by a custom default attribute.
class SomeInputType : ISomeInterface 
{
    public SomeOutputType SomeProperty { get; set; }
    // ... other definitions ...
}

These definition are come from 3rd-party package so I can't change them, I need ignore the property on SomeInputType. So I setup an Ignore callback on TypeResolve, callback body like this:

private static bool IsTypicallyIgnoreTypes(Type type, MemberInfo? memberInfo = null)
{
    if (memberInfo is null) /* other logic */ return false;
    // callback won't receive real type of deriving type if this member is inherited.
    // so this is necessary for get correct deriving type.
    type = memberInfo.ReflectedType ?? type;
    // relate codes like this
    var underType = memberInfo.GetUnderType(); // my extension method to get type of member
    if (type.Name is "SomeInputType" && underType.Name is "SomeProperty") return true;
    // ...
}

It'll not work because: https://github.com/graphql-dotnet/conventions/blob/f6cbc6e8f567b7f9e147dd22f5fc3721f02ebab7/src/GraphQL.Conventions/Types/Resolution/ObjectReflector.cs#L239-L247

Let me explain what happen, implementedProperties will got an MemberInfo on ISomeInterface, and it ReflectedType property is not SomeInputType so won't to ignore. Also, ignore ISomeInterface is not a option because is need to used on output type.

I think the possiable way is change this place, remove items where already exists on properties in implementedProperties.

vcup avatar May 21 '24 08:05 vcup

@vcup just curious: is this a relatively new GraphQL.NET setup or have you used GraphQL.NET and the GraphQL.Conventions library a long time?

Shane32 avatar May 21 '24 13:05 Shane32

It is a new setup, I'm trying make existing AppService able to access on GraphQL.NET through GraphQL.Conventions recently.

vcup avatar May 21 '24 15:05 vcup

I would suggest considering using only the base GraphQL.NET package without the GraphQL.Conventions layer. The base project supports many of the same features, and I can better answer questions and/or respond to pull requests within that project.

If you wish to do so, you'd probably utilize AddAutoClrMappings to create the mappings automatically between CLR types and graph types. AddAutoSchema is also available if you don't want to write the Schema class either. You can customize a IGraphTypeMappingProvider implementation to use derived AutoRegisteringGraphType<> and AutoRegisteringInputGraphType<> instances where you can override any behavior desired. You can also/alternatively register global 'attributes' in GlobalSwitches.GlobalAttributes which are very powerful; to skip a specific property for a specific type, it would be a few lines of code. I also have a separate NuGet package, GraphQL.DI, available if you wish to write mutations similar to MVC controllers, where DI injects services in a similar fashion.

If you wish to use GraphQL.Conventions, you'll need to wait for support by @tlil for any questions or pull requests.

Shane32 avatar May 21 '24 16:05 Shane32

Thanks for you informations, I would try it and open issues on GraphQL.NET if I have!

vcup avatar May 22 '24 08:05 vcup

@vcup let me have a look at this. I spotted a couple of additional quirks so will dig into it and circle back. Thanks for the report.

tlil avatar Jun 01 '24 08:06 tlil