feat: add runtime derived type registration for cross-project polymorphism#132
Merged
xoofx merged 1 commit intoMar 29, 2026
Merged
Conversation
…phism Add YamlDerivedType class and DerivedTypeMappings on YamlPolymorphismOptions to enable registering polymorphic derived types at runtime, without requiring [YamlDerivedType] attributes on the base class. This enables cross-project polymorphism where the base type and derived types live in different assemblies (e.g., clean architecture, plugin systems, modular monoliths). Runtime entries are merged with attribute-based registrations. Attribute-based entries take precedence when the same discriminator or type is registered in both. Includes 31 tests covering property/tag/integer discriminators, roundtrips, mixed attribute+runtime registration, dictionary values, default derived types, unknown discriminator handling, and validation.
Owner
|
Thanks! I will need to add proper support for source generator in a separate commit. |
Contributor
Author
@xoofx Feel free to ask me for any changes, or share your suggestions/improvements that come to your mind. I’m currently porting an application to SharpYaml, so I’ve got a few different use cases I’m working through. I’ll be sending more PRs today along with the context behind each one. |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Motivation
In layered architectures (clean architecture, plugin systems, modular monoliths), the base type and its derived types often live in different projects:
Currently, the only way to register derived types for polymorphic deserialization is via
[YamlDerivedType]attributes placed on the base class. SinceCorecannot referenceNetwork(circular dependency), the attribute cannot be placed on the base class. The only project that sees both the base and derived types isApplication— but SharpYaml provides no way to register derived types from there.This is a hard blocker for cross-project polymorphism. Current workaround is writing a full custom
YamlConverter<TBase>that manually reads tags and dispatches, duplicating whatPolymorphismModelalready does internally.Solution
Add runtime derived type registration via a new
DerivedTypeMappingsdictionary onYamlPolymorphismOptions:New API
YamlDerivedType— Runtime equivalent ofYamlDerivedTypeAttribute:YamlPolymorphismOptions.DerivedTypeMappings— Per-base-type registry:Usage
The base class can optionally have
[YamlPolymorphic]for per-type discriminator config, but[YamlDerivedType]is no longer required.Merge behavior
Runtime entries are additive to attribute-based registrations (
[YamlDerivedType]and[JsonDerivedType]). Attribute-based entries take precedence when the same discriminator or type is registered in both.Changes
YamlDerivedType.cs(new) — Runtime derived type mapping class with 3 constructors matchingYamlDerivedTypeAttributeYamlPolymorphismOptions.cs— AddedDerivedTypeMappingsdictionary propertyYamlObjectConverter.cs— ModifiedPolymorphismModel.TryCreate()to merge runtime registrations with attribute-based entriesYamlRuntimeDerivedTypeTests.cs(new) — 31 tests covering: