Graphql-dotnet: Returned value by the function of InterfaceGraphType.ResolveType is not fully initialized.

Created on 28 Dec 2016  路  3Comments  路  Source: graphql-dotnet/graphql-dotnet

As the title, the returned value (IGraphType) by the function of InterfaceGraphType.ResolveType contains Fields which in each of them has ResolvedType property is set to null. That causes respective fields in the query result to be null.
Currently I need to create ResolvedTypes manually. It'd be nice if those fields are initialized automatically.
Example:

public Queries()
{
    Field<NodeInterfaceGraphType>(
        "node",
        arguments: new QueryArguments(new QueryArgument<NonNullGraphType<IdGraphType>> { Name = "id" }),
        resolve: ctx =>
        {
            return new User
            {
                Name = "abcxyz",
                Address = "ABCXYZ"
            };
        }
    );
}

public class NodeInterfaceGraphType : InterfaceGraphType
{
    public NodeInterfaceGraphType()
    {
        Name = "Node";
        ResolveType = (object obj) =>
        {
            var userGraphType = new UserGraphType();

            // name, address in the query result will be null //////////////////////////////////
            // if the line below were uncommented /////////////////////////////////////////////
            //return userGraphType;

            userGraphType.Fields.Apply(m => m.ResolvedType = Activator.CreateInstance(m.Type));

            // name, address of the query result will contain values ////////////////////////
            return userGraphType;
        };

        AddPossibleType(new UserGraphType());
    }
}

public class UserGraphType : ObjectGraphType
{
    public UserGraphType()
    {
        Interface<NodeInterfaceGraphType>();
        Field<StringGraphType>("name");
        Field<StringGraphType>("address");
    }
}

p.s: sorry for my bad English.

question

All 3 comments

Types need to be registered with the Schema for them to be properly resolved. There should only ever be a single instance of a given type within the Schema. AddPossibleType(new UserGraphType()); and var userGraphType = new UserGraphType(); are creating a new instance of the same type. This should never be done.

userGraphType.Fields.Apply(m => m.ResolvedType = Activator.CreateInstance(m.Type));

You do not need to write that code if you properly register your types with the Schema.

If you need access to a type you should use Dependency Injection. https://github.com/graphql-dotnet/graphql-dotnet/blob/master/docs/learn.md#dependency-injection You can then use constructor-injection to retrieve the type that you need.

Also, instead of using ResolveType on the InterfaceGraphType I would highly suggest using IsTypeOf

Thanks for the answer. I've just tried to use IsTypeOfinstead of ResolveType (on the InterfaceGraphType) and AddPossibleType. And it only works if there is a field that returns UserGraphTypein Schema.Query.
For example:

Field<UserGraphType>( ... );

It looks like if there isn't at least a field which returns UserGraphType in Schema.Query (or maybe Schema.Mutation) then UserGraphType object will not be initialized (UserGraphType's contructor is not even called). So if there is an InterfaceGraphType which returns an object is compatible with UserGraphType, the query result would be null.
I wonder if I'm missing something?

That is correct. If there is no other field that returns the type then you will need to call RegisterType on the Schema.

Was this page helpful?
0 / 5 - 0 ratings

Related issues

Walid-Abdulrazik picture Walid-Abdulrazik  路  3Comments

mahald picture mahald  路  4Comments

damithashyamantha picture damithashyamantha  路  4Comments

tcetin picture tcetin  路  3Comments

csantero picture csantero  路  4Comments