Add PolyType support for efficient serialization integration#835
Conversation
- Add TypeShapeAttribute detection to VogenKnownSymbols - Add utility methods for generating PolyType attribute and marshaler - Integrate PolyType generation into all four generators (Class, Struct, RecordClass, RecordStruct) - PolyType code only generated when PolyType.TypeShapeAttribute is available in compilation Co-authored-by: AArnott <3548+AArnott@users.noreply.github.com>
- Add snapshot tests for PolyType functionality - Create validation script demonstrating expected behavior - Tests verify conditional generation based on PolyType availability Co-authored-by: AArnott <3548+AArnott@users.noreply.github.com>
Removed unnecessary whitespace and comments in PolyTypeTests.cs
|
I'm personally still not clear on how this would work. You said:
I don't get it. If the Or is it supposed to work with the reflection-based shape provider, for example? |
|
The marshaler is required to avoid emitting this schema: {
"Id": {
"Value": 123
},
"Name": "Some Person"
}When we should be emitting this schema: {
"Id": 123,
"Name": "Some Person"
}And yes, this marshaler added here will work anywhere so long as the assembly uses So while this PR doesn't solve the dual source generator problem, there are workarounds for that. But this PR does solve a real schema problem. |
|
The only arguable takeback is that users can hand author this new code today in their own projects, thereby getting the PolyType source generator to work, all in one assembly. But handwriting all this code seems like too high a price for that convenience, and given that without the marshaler, the schema is wrong-by-default, I think this is the lesser of two evils. |
Gotcha. That makes perfect sense now. |
|
The only other piece of feedback I'd have (and this is where we'd need @SteveDunn to chime in) is that we probably want to make this a configurable option in |
Ah, interesting. |
|
Thank you for the PR! I considered whether this should be behind a feature flag like the the other conversion generators. I came to the conclusion that it doesn't; unlike other conversions, if the attribute exists, then the user probably wants the marshaler, and if they don't, then there's no significant overhead, nor additional dependencies that are needed. |
This PR implements support for PolyType integration as requested in issue #834. The implementation conditionally emits additional code when
PolyType.TypeShapeAttributeis available in the compilation, enabling seamless integration between Vogen value objects and PolyType-based serialization libraries like Nerdbank.MessagePack.Problem Statement
PolyType is a high-performance type modeling library that uses source generation to expose type graphs at runtime. However, PolyType's source generator cannot see code emitted by Vogen's source generator, creating a compatibility issue. This forces users to either:
Solution
When
PolyType.TypeShapeAttributeis detected in the compilation, Vogen now automatically generates:IMarshaler<T, TUnderlying>This enables PolyType to efficiently serialize/deserialize the underlying primitive value directly, bypassing the wrapper type and producing optimal schemas.
Example
For a value object like:
When PolyType is available, Vogen now generates:
Implementation Details
PolyType.TypeShapeAttributeis found in the compilationglobal::prefixes and follows existing Vogen patternsBenefits
This resolves the core incompatibility between PolyType and Vogen source generators, enabling developers to use both libraries together seamlessly for efficient, type-safe serialization.
🤖 This PR was prepared in whole or in part by GitHub Copilot (over at AArnott#1). I copied it here so that it could be taken by the upstream repo.