-
Notifications
You must be signed in to change notification settings - Fork 4.7k
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
[release/7.0] Ensure source generated metadata properties are read-only. (#76540) #76899
[release/7.0] Ensure source generated metadata properties are read-only. (#76540) #76899
Conversation
Note regarding the This serves as a reminder for when your PR is modifying a ref *.cs file and adding/modifying public APIs, to please make sure the API implementation in the src *.cs file is documented with triple slash comments, so the PR reviewers can sign off that change. |
Tagging subscribers to this area: @dotnet/area-system-text-json, @gregsdennis Issue DetailsBackport of #76540 to release/7.0 Customer ImpactThe inclusion of the contract customization feature exposes a number of APIs that makes it possible for users to modify aspects of the pre-existing JsonTypeInfo<MyPoco> metadata = MyContext.Default.MyPoco;
// Can modify metadata on the static `Default` context instance.
metadata.CreateObject = null;
metadata.Properties.Clear();
[JsonSerializable(typeof(MyPoco))]
public partial class MyContext : JsonSerializerContext { }
public class MyPoco
{
public int Id { get; set; }
} At first glance this problem might be considered benign, however it has the potential to create a couple of issues:
TestingAdded testing validating that cached source generated metadata is read-only. RiskModerate. Even though the fix is fairly straightforward, it necessitates the introduction of a single public method that can be used by the source generator for locking the metadata it is producing. Adding new APIs at such a late stage carries inherent risks, however this particular method is part of the
|
Approved by Tactics via email. |
We're still deliberating this. We don't have consensus on adding this API in this form to address the issue. We'll hold off on merging this... |
The description and code have been updated to reflect the outcomes from the API review discussions. The APIs have been moved to @carlossanlop -- please let us know how this will affect IntelliSense. Will 7.0 be missing IntelliSense for these APIs in GA? Does that ever get serviced, or would IntelliSense be missing forever in 7.0? Even if that's the case, we can tolerate the gap, but it'll be helpful to know if that's the case. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Once CI is green, this can be merged.
We won't have intellisense for these new APIs in GA. Here is what we will have to do to fix that:
|
Excellent; thanks, @carlossanlop! |
CI is green. |
Backport of #76540 to release/7.0
Customer Impact
The inclusion of the contract customization feature exposes a number of APIs that makes it possible for users to modify aspects of the pre-existing
JsonTypeInfo
contract metadata model. However, it seems that we neglected to freeze modifications for instances instantiated and cached by the source generator:At first glance this problem might be considered benign, however it has the potential to create a couple of issues:
The source generator is aggressively caching metadata instances for performance, so this is effectively introducing global mutable state. Changes in one component can cause unforeseen changes in an unrelated context:
or might be the cause of races when multiple threads are independently attempting to modify contracts:
Direct mutation of source gen metadata breaks the fast-path invalidation logic:
Testing
Added testing validating that cached source generated metadata is read-only.
Risk
Moderate. Even though the fix is fairly straightforward, it necessitates the introduction of a new public method that can be used by the source generator for locking the metadata it is producing. Adding new APIs at such a late stage carries inherent risks, but we've explored the options thoroughly and landed on an API that should also help customers discover that the metadata can be locked and understand when that occurs.
While we don't expect user code will directly invoke either of these APIs, their presence is beneficial. When the metadata is locked, mutation members throw exceptions, and customers can anticipate that possibility by seeing
IsReadOnly
and inspecting its value and when it changes. There is a possibility user code will begin referencingMakeReadOnly
in scenarios we don't anticipate, and/or that we'll want to introduce scoped or validated read-only states in the future. If those scenarios arise, it's possible the shape introduced here won't be ideal. But we have mitigation approaches if needed.