-
-
Notifications
You must be signed in to change notification settings - Fork 63
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
How to deal with NonNull #112
Comments
Maybe with C# 8 and .NET Core 3 the library could drop |
I was also wondering if C#8 nullability feature could be used instead. |
Some time ago I tried (and failed) to make a NonNull Attribute. The problem is that you trust your resolver to return nonnull data, but the only way to communicate that result into the schema is to wrap the type in But looking at your example it seems that this solution may not be sufficient, since it also includes interior non-nullable types, and a single top-level attribute will necessarily be insufficient to describe the nullability of multiple nested types. C# 8 Nullability does sound interesting. |
That should have been the default for GraphQL as well. 😞 |
Yes, unfortunately @shoooe, that's currently the way to go. I've been looking into simplified means of returning data of this structure, incl. using C# 8 nullables. There's a range of challenges with that, in particular around backward-compatibility. Give me some time to continue my current exploration, and I will get back to you. |
We've came up with public class ProductModel
{
public string Id { get; set; }
/*other fields*/
}
[NonNull, NonNullItem]
public virtual IEnumerable<ProductModel> GetProducts(/*params*/) => Enumerable.Empty<ProductModel>();
// or make model non-nullable by default
[NonNull]
public class ProductModel
{
public string Id { get; set; }
}
[NonNull]
public virtual IEnumerable<ProductModel> GetProducts(/*params*/) => Enumerable.Empty<ProductModel>(); The same can be used for arguments (you should "enable" execution filters on arguments previously and set own wrappers to ExecutionFilterAttributeHandler.Wrapper by reflection). |
Any news? I'd be happy to help. |
I was experimenting with the idea of adding support for nullable reference types while maintaining backward compatibility and I stumbled upon this: Basically nullable reference types are implemented via attributes, not with data encoded in the type itself. So the |
Apparently this issue is blocked by: Once that's implemented I'll work on the non null issue myself if nobody is against it. |
Yes, you are right. You'd have to look at the field info.
That'd be great, thanks! |
I actually think it's not a blocker at all. I experimented with non-null introspection and found it was very easy to analyse manually by expecting the attribute. It is very well documented and the new API is just a new convenient way to inspect then. The hardest part for adopting it in the conventions library is to deal the way how types are mapped. Everywhere through the codebase the primary bearer of the type is |
I couldn't find anything. Could you link to the documentation please? Maybe I missed something. |
I probably was under wrong impression that it was well documented :)
When I played with it, it was quite easy to extract nullability. If somebody is willing to start to work on this I can help. |
These days I don't have much time. Maybe next month. |
I was trying to add a new property to every Now, there you get a I read all those links, and they all mention |
@shoe-diamente I can create a simple gist later this week on how to use it. Sorry, cannot do this today or tomorrow. Meanwhile, make sure you compile C# 8 with nullable reference types enabled. |
@Igorbek I can't compile the entire project with nullable references because the library has to also maintain the 90% of other tests for C# 7-. By using the |
Even compiling the entire project with
Even though I import: using System.Runtime.CompilerServices; and then call it as: attributeProvider.GetCustomAttributes(typeof(NullableAttribute)); |
Under "What’s going on under the hood?" of this article you provided it appears that:
I'm attempting to use Namotion.Reflection. |
It looks like they changed the way the attribute gets injected since I experimented with it last time. That being said, the correct way is to use its well-known name and verify, if needed, structurally. We still have access to this type, we just cannot compile-in its statically. Here's a small example of how some method is encoded: Source: using System;
namespace ClassLibrary1
{
public class TestClass
{
public string? Test(string? arg) { return arg; }
}
} Compiled: using System.Runtime.CompilerServices;
namespace ClassLibrary1
{
public class TestClass
{
[return: Nullable(2)]
public string Test([Nullable(2)] string arg)
{
return arg;
}
}
}
using Microsoft.CodeAnalysis;
using System.Runtime.InteropServices;
// NOTE: this is the same assembly
namespace System.Runtime.CompilerServices
{
[CompilerGenerated]
[Embedded]
internal sealed class NullableAttribute : Attribute
{
public readonly byte[] NullableFlags;
public NullableAttribute([In] byte obj0): base()
{
this.NullableFlags = new byte[1]{ obj0 };
}
public NullableAttribute([In] byte[] obj0): base()
{
this.NullableFlags = obj0;
}
}
} |
Reasonably I don't have time to work on this unfortunately for the next few months. This is were I stopped: https://github.com/shoe-diamente/conventions. I'd recommend using Namotion.Reflection. There's a contextual type type which should replace |
Nevermind. Even without solving the Therefore I'll may have some time to work on either documentation or this issue. Is anybody else willing to help? |
Hello,
what's the proper way to deal with
NonNull<T>
not beingT
?Let's assume that you have a resolver like:
what's the proper way to return
list
?Do I have to add some boilerplate code like:
?
I've tried to look at both examples, but none of those seem to use
NonNull
for output types.The text was updated successfully, but these errors were encountered: