Add interface collection codecs#10104
Merged
Merged
Conversation
Add open generic codecs and copiers for common generic collection interfaces so declared interface fields can serialize unsupported runtime collection implementations using concrete fallback shapes. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Report interface collection fallback payloads using the concrete interface codec type instead of fallback collection implementations. Add a generalized resolver and serializer snapshot coverage for the codec aliases. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Clear thread-local serializer and copy context pools when their owning service provider is disposed so test-created serializer providers do not remain rooted. Stop writing random seeds for passing serialization test kit tests and add lifetime regression coverage. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Share serializer service providers through an xUnit class fixture instead of a static cache, while keeping the existing TestKit constructors for compatibility. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Restore random seed output in FieldCodecTester and CopierTester after moving seed creation into the shared serialization tester base. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Contributor
There was a problem hiding this comment.
Pull request overview
This PR addresses Orleans serializer failures when collection-typed fields are declared as common collection interfaces (eg, IReadOnlyList<T>, ISet<T>, IDictionary<TKey,TValue>) but are assigned runtime collection implementations which do not have concrete codecs (such as compiler-generated collection-expression types). It adds open-generic interface codecs/copiers with safe fallback shapes, and updates the serialization test infrastructure to reduce per-test DI container churn while ensuring pooled state is released on disposal.
Changes:
- Added interface collection codecs/copiers for enumerable/list-like, set-like, and dictionary-like generic interfaces, including a resolver to handle codec-surrogate runtime types.
- Updated serializer/copy-context pools to be disposable and to release thread-local pooled state on
ServiceProviderdisposal. - Added/updated unit tests and snapshot verifications, plus introduced a shared
SerializationTester/fixture for TestKit-based tests.
Show a summary per file
| File | Description |
|---|---|
| test/Orleans.Serialization.UnitTests/snapshots/InterfaceCollectionRegressionTests.SetInterfaceFallback_Formatted_MatchesSnapshot.verified.txt | Adds snapshot verifying set-interface fallback wire format. |
| test/Orleans.Serialization.UnitTests/snapshots/InterfaceCollectionRegressionTests.ReadOnlySetInterfaceFallback_Formatted_MatchesSnapshot.verified.txt | Adds snapshot verifying read-only set-interface fallback wire format. |
| test/Orleans.Serialization.UnitTests/snapshots/InterfaceCollectionRegressionTests.ReadOnlyListInterfaceFallback_Formatted_MatchesSnapshot.verified.txt | Adds snapshot verifying read-only list-interface fallback wire format. |
| test/Orleans.Serialization.UnitTests/snapshots/InterfaceCollectionRegressionTests.ReadOnlyDictionaryInterfaceFallback_Formatted_MatchesSnapshot.verified.txt | Adds snapshot verifying read-only dictionary-interface fallback wire format. |
| test/Orleans.Serialization.UnitTests/snapshots/InterfaceCollectionRegressionTests.ReadOnlyCollectionInterfaceFallback_Formatted_MatchesSnapshot.verified.txt | Adds snapshot verifying read-only collection-interface fallback wire format. |
| test/Orleans.Serialization.UnitTests/snapshots/InterfaceCollectionRegressionTests.ListInterfaceFallback_Formatted_MatchesSnapshot.verified.txt | Adds snapshot verifying list-interface fallback wire format. |
| test/Orleans.Serialization.UnitTests/snapshots/InterfaceCollectionRegressionTests.EnumerableInterfaceFallback_Formatted_MatchesSnapshot.verified.txt | Adds snapshot verifying enumerable-interface fallback wire format. |
| test/Orleans.Serialization.UnitTests/snapshots/InterfaceCollectionRegressionTests.DictionaryInterfaceFallback_Formatted_MatchesSnapshot.verified.txt | Adds snapshot verifying dictionary-interface fallback wire format. |
| test/Orleans.Serialization.UnitTests/snapshots/InterfaceCollectionRegressionTests.CollectionInterfaceFallback_Formatted_MatchesSnapshot.verified.txt | Adds snapshot verifying collection-interface fallback wire format. |
| test/Orleans.Serialization.UnitTests/SerializerServiceProviderLifetimeTests.cs | Adds tests ensuring pooled serializer state can be GC’d after DI container disposal and that returning pooled state post-disposal is safe. |
| test/Orleans.Serialization.UnitTests/ProtobufSerializerTests.cs | Updates tests to use shared SerializationTesterFixture. |
| test/Orleans.Serialization.UnitTests/NewtonsoftJsonCodecTests.cs | Updates tests to use shared SerializationTesterFixture. |
| test/Orleans.Serialization.UnitTests/MessagePackSerializerTests.cs | Updates tests to use shared SerializationTesterFixture. |
| test/Orleans.Serialization.UnitTests/MemoryPackSerializerTests.cs | Updates tests to use shared SerializationTesterFixture. |
| test/Orleans.Serialization.UnitTests/InterfaceCollectionCodecTests.cs | Adds comprehensive codec/copier tests + regression tests for interface-typed collections (including snapshots). |
| test/Orleans.Serialization.UnitTests/ConverterTests.cs | Updates converter tests to use shared SerializationTesterFixture. |
| test/Orleans.Serialization.UnitTests/BuiltInCodecTests.cs | Updates built-in codec tests to use shared SerializationTesterFixture. |
| src/Orleans.Serialization/Session/SerializerSessionPool.cs | Switches to a thread-local concurrent pool and makes the pool disposable to release thread-local state. |
| src/Orleans.Serialization/Invocation/Pools/ConcurrentObjectPool.cs | Adds IDisposable and disposal logic to clear thread-local stacks, plus disposed-state guarding. |
| src/Orleans.Serialization/Hosting/ServiceCollectionExtensions.cs | Registers InterfaceCollectionCodecResolver as a generalized codec. |
| src/Orleans.Serialization/Codecs/InterfaceCollectionCodecs.cs | Introduces interface collection codecs/copiers and the codec-type resolver for fallback/surrogate handling. |
| src/Orleans.Serialization/Cloning/IDeepCopier.cs | Makes CopyContextPool disposable so DI disposal can release pooled state. |
| src/Orleans.Serialization.TestKit/ValueTypeFieldCodecTester.cs | Adds ctor overload supporting the new shared fixture-based tester pattern. |
| src/Orleans.Serialization.TestKit/SerializationTester.cs | Adds shared tester base + fixture for reusing a service provider per test class. |
| src/Orleans.Serialization.TestKit/FieldCodecTester.cs | Refactors to inherit from SerializationTester, enabling fixture reuse and centralizing service provider lifetime. |
| src/Orleans.Serialization.TestKit/CopierTester.cs | Refactors to inherit from SerializationTester, enabling fixture reuse and centralizing service provider lifetime. |
| src/api/Orleans.Serialization/Orleans.Serialization.cs | Updates public API surface for CopyContextPool/SerializerSessionPool to implement IDisposable. |
| src/api/Orleans.Serialization.TestKit/Orleans.Serialization.TestKit.cs | Updates public API surface for new SerializationTester/fixture and updated tester base types/constructors. |
Copilot's findings
- Files reviewed: 27/28 changed files
- Comments generated: 2
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
This was referenced May 16, 2026
This was referenced Jun 14, 2026
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 subscribe to this conversation on GitHub.
Already have an account?
Sign in.
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.
Fixes #8934
Problem
Issue #8934 reports failures when interface-typed collection fields are assigned runtime collection implementations which Orleans does not have concrete codecs for, such as collection-expression generated types. Those fields currently fall through to runtime-type serialization and can fail with
CodecNotFoundException.Solution
This adds regular open-generic codecs and copiers for common generic collection interfaces, including enumerable/list-like, set-like, and dictionary-like interfaces. The codecs preserve existing concrete runtime serialization when a concrete codec exists, and otherwise fall back to concrete BCL collection shapes (
List<T>,HashSet<T>, andDictionary<TKey, TValue>). The fallback writes bounded capacity hints, capped at 16K elements, so deserialization can preallocate efficiently without trusting accidentally huge reported counts.The accompanying tests cover the issue regression, copy behavior, frozen collections, capacity-hint capping, and preservation of known concrete runtime behavior.
Notes
Non-generic collection interfaces and lookup/query/streaming interfaces remain out of scope for this change.
Microsoft Reviewers: Open in CodeFlow