-
Notifications
You must be signed in to change notification settings - Fork 4.8k
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
Provide a public api to "lock" a JsonSerializerOptions
#54482
Comments
Tagging subscribers to this area: @eiriktsarpalis, @layomia Issue DetailsBackground and MotivationWe have a set of contract libraries that we create, all of which depend on a "core" contract library, which defines the json serialization options as a static property. Currently, this property is internal, and we use The reason we don't just have it as public is that we don't want consumers of our contracts to modify it (as it's a shared static instance). However, reading through the source of I do not know what name would be best for such a method, so the one below is just a suggestion. Proposed APInamespace System.Text.Json
{
public class JsonSerializerOptions
{
+ public void EnsureImmutable(); Usage Examples public static class JsonContracts
{
static JsonContracts()
{
SerializerOptions = new JsonSerializerOptions
{
PropertyNamingPolicy = JsonNamingPolicy.CamelCase,
PropertyNameCaseInsensitive = true,
};
SerializerOptions.ConfigureForNodaTime(DateTimeZoneProviders.Tzdb);
SerializerOptions.EnsureImmutable();
}
public static JsonSerializerOptions SerializerOptions { get; }
} Alternative DesignsKeeping it internal works, but requires me to configure RisksI don't see any risk with this API. It would also help codify the fact that a JsonSerializerOptions can be "locked" (today it just happens implicitly).
|
As far as I can tell, you can already do this by using the var options = new JsonSerializerOptions();
options.WriteIndented = true; // ok
JsonSerializer.Serialize<object>(null, options);
options.WriteIndented = true; // exception That doesn't necessarily mean this API shouldn't be added, just that it's technically not necessary. (I'm also assuming that this behavior is guaranteed, but I'm not sure it actually is.) Also, the pattern where you can make a mutable object immutable is often called "freezable" and the method to do it |
@svick Yeah, that's the trick I'm currently experimenting with. But it's highly unintuitive, likely to be removed if you don't add a comment that explains why you're doing this, etc. And again, it's implicit "freezing". Similarly, I could also do this using reflection and setting private members, but that's opening myself up to non-breaking changes breaking me. |
Sounds reasonable, but wouldn't we also need to expose a boolean property indicating that the instance is locked? cc @layomia @steveharter |
I purposefully didn't add one to this suggestion, because I don't think it's strictly necessary. Exceptions on attempts to modify (as today), and an |
Yeah we should probably add this as well. |
namespace System.Text.Json;
public partial class JsonSerializerOptions
{
public bool IsReadOnly { get; }
public void MakeReadOnly();
} |
|
Looks like it requires a more general approach. One of the approaches could be introducing a special interface and implementing it by interface ICantThinkOfAName
{
bool IsReadOnly { get; }
void MakeReadOnly();
} |
We have a design rules that says "if you can't think of a method accepting the interface the interface is useless". That's the case here; it would just work as way to codify a convention, which isn't all that useful. (the fact that you can't think of a good name is another indicator in this regard, as this isn't really a concept) |
Yes, that would be the intention. |
would it make sense to add identical APIs to JsonTypeInfo, JsonPropertyInfo, DefaultJsonTypeInfoResolver? |
I think it probably does for |
Any publicly accessible "lock" method in |
Background and Motivation
We have a set of contract libraries that we create, all of which depend on a "core" contract library, which defines the json serialization options as a static property. Currently, this property is internal, and we use
InternalsVisibleTo
to give access to this property to the actual contracts projects, but it would be preferable to just have this be a public property.The reason we don't just have it as public is that we don't want consumers of our contracts to modify it (as it's a shared static instance). However, reading through the source of
JsonSerializerOptions
I noticed that it contains a VerifyMutable method, meaning that there are cases where a JsonSerializerOptions is not mutable. I suggest enabling a simple public API that can take a givenJsonSerializerOptions
and "lock" it, or "make it immutable", so that it's safe to share in library code. This would be a no-op if the options is already immutable.I do not know what name would be best for such a method, so the one below is just a suggestion.
Proposed API
Usage Examples
Alternative Designs
We might want to consider exposing equivalent functionality to JsonTypeInfo and JsonPropertyInfo, whose design uses a similar locking design. We're also not certain about naming, the obvious alternative being
IsLocked
/Lock()
but there are concerns that this connotes with exclusive locking.Risks
I don't see any risk with this API. It would also help codify the fact that a JsonSerializerOptions can be "locked" (today it just happens implicitly).
The text was updated successfully, but these errors were encountered: