0

I'm trying to learn how to use HotChocolate and GraphQL as an alternative to REST APIs. Now my project does not allow implicit nullable reference types so when I have a model I need a constructor to set every of my properties that aren't nullable to a value.

Below you'll find the model I'm using:

public class TaskEntity
{
    public TaskEntity(string name)
    {
        Name = name ?? throw new ArgumentNullException(nameof(name));
        TaskCategoryEntities = new List<TaskCategoryEntity>();
    }

    public Guid Id { get; set; }

    public string Name { get; set; }

    public ICollection<TaskCategoryEntity> TaskCategoryEntities { get; set; }
}

And this is the query I have set up:

[ExtendObjectType(nameof(Query))]
public class TaskQuery
{
    [UseProjection]
    [UseFiltering]
    [UseSorting]
    public IQueryable<TaskEntity> Tasks([Service] TaskifyDbContext context, [Service] IMapper mapper)
    {
        return context.Tasks;
    }
}

Type 'Dev.Taskify.Resources.Entities.TaskEntity' does not have a default constructor (Parameter 'type')

Ofcourse I can resolve this by adding a default constructor in TaskEntity but then I'm greeted by this warning in my IDE

Non-nullable properties 'Name', 'TaskCategoryEntities' are uninitialized. Consider declaring the properties as nullable.

Is there a way for my query to working without the default ctor? If not, why not?

Giani Noyez
  • 481
  • 3
  • 8
  • 17

2 Answers2

0

Based on the warning you are getting, I'm assuming you already have the nullable featured turn on in your csproj file. It is my experience with HC that all you need to ensure is that your schema is coming out correctly and HC will enforce it for you. In your example, the schema generated will show that Name and TaskCategorEntities are not optional. Thus, if you inititate an object leaving any of those values null, HC to throw an exception indicating that the data you're trying to send violates the schema. As for the build warning you are getting, you can either add the required (https://learn.microsoft.com/en-us/dotnet/csharp/language-reference/keywords/required) keyword or all = null! at the end of both properties--the first enforcing property initialization and the second being a compile indicator that you promise this will never be null.

In addition, if you find that HC isn't automatically detecting your intention to have those fields be non-null, you can decorate them with the [GraphQLNonNullType] attribute and for the inner type of the collection, [GraphQLType(typeof(ListType<NonNullType<TaskCategoryEntity>>))].

chrisdrobison
  • 1,323
  • 2
  • 13
  • 24
0

You can initialize Name and other properties in the default constructor:

public TaskEntity()
{
    Name = string.Empty;
    TaskCategoryEntities = Array.Empty<TaskCategoryEntity>();
}
Orace
  • 7,822
  • 30
  • 45