Infer scalar types from specially-formatted dotnet classes #4846
Replies: 6 comments
-
This was a bad idea, it needs to be string since the underlying type in the graph is a string, serialization of decimal to/from string varies depending on culture. |
Beta Was this translation helpful? Give feedback.
-
I would suggest some minor tweaks on this. Note in the code above, I write some attributes multiple times, just to show what's allowed in my suggested implementation. I'm not saying you could have multiple [ScalarType] // get's name from class
[ScalarType(Name = "TimeSpan")] // explicit
public struct Money {
readonly decimal _value;
// By default, a constructor that accepts a string value is the default parser
constructor(string value) => _value = MagicallyParseValue(value);
// This can be overriden with a static attributed method
[ScalarParse]
public static Money Parse(string value) => new Money(value);
// And even with a try-parse one
[ScalarParse]
public static bool TryParse(string value, out Money money) { .. }
// By default, for serializing, ToString is used
public override string ToString() => _value.ToString(CultureInfo.InvariantCulture);
// This can also be overridden, but by an instance method instead
[ScalarSerialize]
public string Serialize() => ToString();
// Or a property
[ScalarSerialize]
public string StringValue => ToString();
// Even try-serialize
[ScalarSerialize]
public bool TrySerialize(out string serialized) { .. }
} |
Beta Was this translation helpful? Give feedback.
-
To add on; in addition to working with constructers (when no method is attributed with [Edit] |
Beta Was this translation helpful? Give feedback.
-
Based on this issue and the slack thread I think we have two use cases:
I was thinking about #2, but I wrote the issue with #1 as the example. A number of improvements for #1 were suggested in slack, and those make sense. @Alxandr's suggestion on constructors also makes sense, although this could get weird for structs, since there are rules about what parameters their constructors must have. I'd vote for having the Parse or TryParse method be available as a default, also since that matches the |
Beta Was this translation helpful? Give feedback.
-
For me this would be too much ... if we have so many attributes the really what is the benefit of doing this we have a scalar type that can be implemented. If we want to reinvent around this it should be simple... having this much attributes feels complicated there is now guidance around this like methods that I could override. We have to be careful with things like this. It has to feel intuitive. As far as I understood the initial idea was to help people with the simple scalars that we have most of the time. Also scalars should not be implemented on a whim and should follow specs. Like the DateTime scalar which does not just do a ToString on DateTime. It actually implements the RFC3339 like in the GraphQL 2020 spec defined. So let us focus on introducing something simple that allows us to create a simple scalar with minimal effort.... one or two methods. Scalar.Create("Foo", s => TimeSpan.Parse(s)) |
Beta Was this translation helpful? Give feedback.
-
I think there are two different uses here. The code you posed @michaelstaib matches what I would think of as Code First (I might be mixing my terminology here, so please correct me if I do) in which you create your own My example above is for what I believe you've called Pure Code First. This is a string-idempotent type which within the same type (not an extra |
Beta Was this translation helpful? Give feedback.
-
Is your feature request related to a problem? Please describe.
Declaring custom scalar types is repetitive and isn't really a "pure code first" path.
Describe the solution you'd like
I'd like hotchocolate to be able to infer scalar types based on common dotnet patterns.
For example, string-serializable types are either:
a) implicitly/explicitly convertible to/from a string
b) expose a static
Parse(string s)
factory-method that returns an instance of the class and have aToString()
overload.Describe alternatives you've considered
Currently I create a base-class to help facilitate this process, but it would be easier if the framework could infer this situation.
I'd like to be able to have a class like this:
Then I'd like to be able to do:
And I'd like the framework to be able to infer what's going on. Alternatively, if the type must be explicitly convertible to string, that could work too.
Beta Was this translation helpful? Give feedback.
All reactions