Skip to content

STJM: keep a copied options' migration registration on .NET 11 through the union classifier #220

Description

@egil

Context

PR #213 registers migration as a resolver at the front of TypeInfoResolverChain and remembers the registration per options instance (MigrationScope, keyed in a ConditionalWeakTable) and per chain object (ScopesByChain, which is what a copy made with new JsonSerializerOptions(original) resolves through until it changes its own chain).

A copy that replaces or extends its resolver before any migration lookup runs on it, while the migration entry sits behind an application-defined resolver, carries nothing that identifies its origin:

var copy = new JsonSerializerOptions(original);
copy.TypeInfoResolver = new ForwardingResolver(copy.TypeInfoResolverChain[0]);
copy.AddJsonMigrationSupport();   // registers again with the configuration it passes

The chain walk cannot see through the wrapper, probing the wrapper would call a user's resolver during registration (and freeze a DefaultJsonTypeInfoResolver's Modifiers), and inferring from chain shape was shown to misattribute registrations between independent options. So such a copy registers again, like any options whose chain no longer shows the entry.

Idea

On .NET 11 the copy constructor also copies TypeClassifiers, and AddJsonMigrationSupport() adds a JsonMigratableUnionTypeClassifier instance there. That instance is ours, is added only by registration, and is never shared between independently created options, so it is sound provenance: give it an internal constructor that carries the JsonMigrationTypeInfoResolver, and let MigrationScope.FindCached look for it before structural discovery. Copies then keep their registration on .NET 11 regardless of what they do to their chain, while the documented re-registration stays the .NET 10 behavior.

Out of scope for #213 because it makes behavior differ by target framework and needs its own documentation.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions