Support reuse of JsonSerializerContext's from libraries, so as not to generate duplicate serialization code #86876
Description
Background and motivation
As the system.text.json code generation serialization usage become more widespread, libraries will (and do) expose their serialization contexts.
If in a local project, that has a local type, that contains a property of a type for a library as above, where the local type is registered as part of the local project serialization context (via [JsonSerializable] attribute) it also generates serialization code for the libraries type.
The net effect is that there is duplicated serialization code generated for that library type and its sub components with the locally generated serialization context.
If there were a new attribute that indicated that a given type already has a code generated serializer defined in another (libraries or otherwise ) public serialization context, the local generated serialization context could hook into that library's generated serialization code for that libraries type.
It seems sensible to uses the libraries generated serialization code for its type, as built into the "released" library than regenerating that code locally, that my for some reason behave differently invalidating the implementation contract of the library.
API Proposal
public record MyLocalType
{
[JsonPropertySerializationContext(typeof(LibrariesSerializationContext))] public TypeInLibrary MyUsageOfLibraryType { get; set; }
}API Usage
As above.
Alternative Designs
None that I know of.
Risks
N/A
Activity
layomia commentedon Jun 22, 2023
I believe this is already possible by adding an instance of the desired context type to the new
JsonSerializerOptions.TypeInfoResolverChainproperty. That would use the context across the entire input type graph.I'm not sure of the best way to achieve per-property context use like shown above, but I imagine a combination of using
DefaultJsonTypeInfoResolver.Modifiersfeature and consulting a static instance of of the desired context within the modifier implementation would work. You'd usedesiredContext.GetTypeInfoto retrieve generated metadata & use it to populate the modifier's inputJsonTypeInfo. Admittedly this is complex but an inbox API would probably work out all the kinks.These approaches use runtime configuration (vs using declarative attributes like shown above), but the new attribute would probably use similar techniques.
We've had related discussions about resolving customization differences across assemblies (i.e. stuff specified using
JsonSerializerOptions/Context/Attributes), the downsides of metadata sharing (particularly any sort of implicitly used global caches), sharing metadata for primitives across assemblies etc. There's prior art for some of these considerations with how theTypeInfoResolverChainworks.