Skip to content

Add interface collection codecs#10104

Merged
ReubenBond merged 8 commits into
dotnet:mainfrom
ReubenBond:issue-8934-interface-codecs
May 15, 2026
Merged

Add interface collection codecs#10104
ReubenBond merged 8 commits into
dotnet:mainfrom
ReubenBond:issue-8934-interface-codecs

Conversation

@ReubenBond

@ReubenBond ReubenBond commented May 14, 2026

Copy link
Copy Markdown
Member

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>, and Dictionary<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

ReubenBond and others added 5 commits May 14, 2026 16:12
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>

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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 ServiceProvider disposal.
  • 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

Comment thread test/Orleans.Serialization.UnitTests/InterfaceCollectionCodecTests.cs Outdated
Comment thread test/Orleans.Serialization.UnitTests/SerializerServiceProviderLifetimeTests.cs Outdated
ReubenBond and others added 2 commits May 15, 2026 12:30
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
@ReubenBond ReubenBond linked an issue May 15, 2026 that may be closed by this pull request
@ReubenBond ReubenBond added this pull request to the merge queue May 15, 2026
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Merged via the queue into dotnet:main with commit 5e16f6f May 15, 2026
1 check passed
@ReubenBond ReubenBond deleted the issue-8934-interface-codecs branch May 15, 2026 22:02
@cptjazz

cptjazz commented May 16, 2026

Copy link
Copy Markdown

Also closes #9032 and #8964

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

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Collection Expression syntax not compatible with orleans serializer

3 participants