Open AArnott opened 2 weeks ago
Once you have naming policy support, it would be great PolyType could offer a map of properties and constructor parameters, or (even simpler) the properties themselves should have something more than HasSetter
that would indicate whether the constructor allows indirectly setting the property.
The reason for this is that I don't want a serializer to include serialization of a property that has only a getter and no constructor parameter either.
it would be great PolyType could offer a map of properties and constructor parameters, or (even simpler) the properties themselves should have something more than
HasSetter
that would indicate whether the constructor allows indirectly setting the property.
The parameters of constructor shapes already includes settable members modulo those matching constructor parameters.
Beyond that though, the library doesn't try to explicitly pair properties to parameters or fail if no match is found. System.Text.Json does do this fairly aggressively and we've received feedback from users that this is undesirable in scenaria where you only care about serialization or deserialization but not about being able to roundtrip values. This feels like a policy that can be enforced by individual consumers.
Beyond that though, the library doesn't try to explicitly pair properties to parameters or fail if no match is found.
Let's put the "fail if not match is found" or skipping serialization on no match aside for a moment.
I still have to (at present) write the code to match a serialized property name to a constructor parameter. This is a pain, and requires that I decide the policy for how user's constructor parameter names must match the property name. Consider this case:
class Foo
{
public Foo(int a);
public int A { get; }
}
By default, this might serialize to JSON like this:
{ "A": 5 }
Now, upon _de_serialization, how should the deserializer decide what to do with the JSON A
property? It doesn't match the a
constructor parameter. So should it drop it, or should it decide based on a camelCase/PascalCase match, or should it be totally case-insensitive?
From a PolyType perspective, we have an opportunity perhaps to unify how serializers work including potentially some of their policies. Personally, for a fresh MessagePack library such as the one I'm building, I'd rather not have to decide this policy and rely on a common framework like PolyType to define it, so that users can define their types once with PolyType conformance, and then switch from serializing to JSON to MsgPack to Cbor -- and have it all Just Work instead of one of those formats failing because they don't know that property A
should be matched with ctor parameter a
.
Now, upon _de_serialization, how should the deserializer decide what to do with the JSON A property? It doesn't match the a constructor parameter. So should it drop it, or should it decide based on a camelCase/PascalCase match, or should it be totally case-insensitive?
These are all valid options. I don't believe this association should be the purview of shapes but a matter of policy in individual serializers. We can of course choose to expose helpers that implement either of these policies in a streamlined fashion.
I'd rather not have to decide this policy and rely on a common framework like PolyType to define it, so that users can define their types once with PolyType conformance, and then switch from serializing to JSON to MsgPack to Cbor
I agree that this would be a desirable goal. At some point we could consider implementing something like Serde.NET on top of PolyType using a common set of conventions. Adding support for a new format would be as simple as implementing a pair of reader/writer classes.
Another use case for consistent mapping from constructor parameters to properties: https://github.com/AArnott/Nerdbank.MessagePack/issues/89 needs to decide which property is impacted by the default value as specified as a default parameter value in a primary constructor so that we can decide whether to serialize that property.
From this conversation @eiriktsarpalis said:
I was thinking the same thing.