Skip to content

fix: support single-file metadata discovery - #11054

Merged
ReubenBond merged 14 commits into
dotnet:mainfrom
ReubenBond:rb-fix-support-single-file-metadata
Sep 4, 2026
Merged

ReubenBond merged 14 commits into
dotnet:mainfrom
ReubenBond:rb-fix-support-single-file-metadata

Conversation

@ReubenBond

@ReubenBond ReubenBond commented Sep 3, 2026 •

Copy link
Copy Markdown
Member

Problem

The .NET single-file analyzer reported file-based metadata access in runtime version reporting and serializer application-part discovery. Bundled assemblies have no Assembly.Location, and DependencyContext discovery requires physical assembly files.

Solution

Read the runtime product version from AssemblyInformationalVersionAttribute, preserving the assembly-version fallback and build-configuration suffix. Serializer discovery now starts from generated ApplicationPartAttribute metadata and loaded assemblies, while dependency-context discovery runs only when assembly files are available. The public file-based API is annotated with RequiresAssemblyFiles, and the single-file analyzer is enabled for the affected net10 projects. Focused tests cover fileless version metadata, generated application-part traversal, entry-assembly discovery, and the public assembly-file contract.

Rationale

Assembly attributes and generated application-part registrations are available from memory-loaded assemblies, so they provide stable metadata and discovery in bundled apps. Framework-dependent deployments retain dependency-context scanning for assemblies which have not yet loaded, while callers of the explicit file-based API receive an accurate compatibility contract.

Microsoft Reviewers: Open in CodeFlow

Copilot AI lite review requested due to automatic review settings September 3, 2026 21:40

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.

Copilot review overview

🟢 Approval recommended

The changes align with the PR’s stated single-file goals, add explicit compatibility contracts for file-based APIs, and include targeted tests covering the new behavior.

Review tier: Lite
Findings: None

What changed in this PR

This PR improves Orleans’ compatibility with .NET single-file deployments by removing reliance on file-based assembly metadata (Assembly.Location, DependencyContext.Load) in core runtime version reporting and serialization application-part discovery, while making file-based discovery explicitly opt-in/annotated.

Changes:

  • Update runtime version reporting to use AssemblyInformationalVersionAttribute (with assembly-version fallback) so it works when assemblies have no physical path.
  • Rework serialization application-part discovery to start from generated ApplicationPartAttribute metadata + loaded assemblies, and gate dependency-context scanning behind an “assembly files available” check with RequiresAssemblyFiles.
  • Add focused unit tests and enable the single-file analyzer for the affected net10.0 targets.
File Description
test/​Orleans.Serialization.UnitTests/​ReferencedAssemblyProviderTests.cs Adds tests validating application-part traversal and the RequiresAssemblyFiles contract.
test/​Orleans.Core.Tests/​RuntimeVersionTests.cs Adds tests ensuring runtime version reporting works for fileless/dynamic assemblies.
src/​Orleans.Serialization/​Orleans.Serialization.csproj Enables the single-file analyzer for net10.0 builds.
src/​Orleans.Serialization/​Hosting/​ReferencedAssemblyProvider.cs Switches discovery to entry-assembly/generated metadata + loaded assemblies; gates dependency-context scanning behind file availability and annotates file-based API.
src/​Orleans.Core/​Runtime/​RuntimeVersion.cs Replaces file-based product version lookup with informational-version attribute lookup and preserves fallback behavior.
src/​Orleans.Core/​Orleans.Core.csproj Enables the single-file analyzer for net10.0 builds.
src/​api/​Orleans.Serialization/​Orleans.Serialization.cs Updates the public API surface to include the RequiresAssemblyFiles annotation on dependency-context discovery.

💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.

@github-actions

github-actions Bot commented Sep 3, 2026 •

Copy link
Copy Markdown
Contributor

Code coverage

Metric Pull request
Lines 81.88% (106,476 / 130,034)
Branches 70.94% (30,376 / 42,818)

Report-only conclusion: current-main baseline stale.

The newest successful coverage run tested 114a827, not current main 9cf2fac.

Coverage combines every CI test matrix job, including providers, CodeGen, .NET 8/10, Linux, Windows, and macOS, using canonical physical source and branch identities.

The comparison remains report-only while normal line and branch variance is calibrated.

Coverage details

Copilot AI review requested due to automatic review settings September 3, 2026 22:36

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.

Copilot review overview

🟢 Approval recommended

The changes align with the stated single-file compatibility goals, keep a clear compatibility contract via RequiresAssemblyFiles, and include targeted unit test coverage for the new behaviors.

Review tier: Lite
Findings: None

@ReubenBond
ReubenBond enabled auto-merge September 3, 2026 23:07
@ReubenBond

Copy link
Copy Markdown
Member Author

The Azure Storage net8 failure is unrelated to this change and is tracked by #11033 (SMS_StreamRel_AllSilosRestart_PubSubCounts observed publisher count 2 instead of 1 after restart). The failed job has been rerun on the unchanged PR head.

Copilot AI review requested due to automatic review settings September 3, 2026 23:34
@ReubenBond
ReubenBond force-pushed the rb-fix-support-single-file-metadata branch from da70def to 5556532 Compare September 3, 2026 23:34

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.

Copilot review overview

🟢 Approval recommended

The functional changes align with the stated single-file goals and are backed by focused tests, with only a minor doc-comment inconsistency noted.

Review tier: Lite
Findings: 1 Low severity

New issues introduced by this change (1)
Severity Finding
Low severity src/​Orleans.Core/​Runtime/​RuntimeVersion.cs — The XML doc comment for Current still describes the old FileVersionInfo.ProductVersion format…

Comment thread src/Orleans.Core/Runtime/RuntimeVersion.cs
Copilot AI review requested due to automatic review settings September 3, 2026 23:43

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.

Copilot review overview

🔵 Needs a closer look

The new AssemblyFilesAvailable gate can incorrectly disable dependency-context discovery when the entry assembly is dynamic, even though the discovery path supports dynamic assemblies via DependencyContext.Default.

Review tier: Lite
Findings: None

Issues resolved since last review (1)
Severity Finding
Low severity src/​Orleans.Core/​Runtime/​RuntimeVersion.cs — The XML doc comment for Current still describes the old FileVersionInfo.ProductVersion format… View resolved comment
Suppressed comments (1)

Previously missed (1) — in code that hasn't changed since the last review.

src/Orleans.Serialization/Hosting/ReferencedAssemblyProvider.cs:225

  • AssemblyFilesAvailable treats a dynamic entry assembly as “no assembly files available” because it always prefers the entry assembly when non-null. That prevents dependency-context discovery even though AddFromDependencyContext explicitly handles dynamic assemblies via DependencyContext.Default. Consider falling back to the provider assembly when the entry assembly is dynamic so the availability check matches the discovery behavior.

Copilot AI review requested due to automatic review settings September 3, 2026 23:53
@ReubenBond

Copy link
Copy Markdown
Member Author

AssemblyFilesAvailable treats a dynamic entry assembly as “no assembly files available” because it always prefers the entry assembly when non-null.

Addressed in eafe43c10: dynamic or absent entry assemblies now use the Orleans.Serialization assembly for the physical-file availability probe, while the original dynamic entry assembly is still passed to AddFromDependencyContext so it selects DependencyContext.Default. AssemblyFileAvailabilityUsesProviderAssemblyForDynamicEntryAssembly covers the regression.

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.

Copilot review overview

🟢 Approval recommended

The changes align with the PR’s stated single-file compatibility goals and include targeted test coverage for the new behavior and contracts.

Review tier: Lite
Findings: None

Suppressed comments (1)

Previously missed (1) — in code that hasn't changed since the last review.

src/Orleans.Serialization/Hosting/ReferencedAssemblyProvider.cs:137

  • The RequiresAssemblyFiles message hard-codes GetRelevantAssemblies as a string, so a rename would silently leave the guidance stale. Since nameof(...) is a compile-time constant, you can embed it in the message to keep it refactor-safe.

Copilot AI review requested due to automatic review settings September 4, 2026 00:02
@ReubenBond

Copy link
Copy Markdown
Member Author

The RequiresAssemblyFiles message hard-codes GetRelevantAssemblies as a string, so a rename would silently leave the guidance stale.

Addressed in 10e7b0573: the attribute message now uses nameof(GetRelevantAssemblies), preserving the same emitted metadata text while keeping the source guidance rename-safe. The focused provider test suite still passes.

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.

Copilot review overview

🟢 Approval recommended

The changes align with the stated single-file compatibility goals and include targeted tests, with only minor build-target optimization feedback noted.

Review tier: Lite
Findings: None

Suppressed comments (1)

Previously missed (1) — in code that hasn't changed since the last review.

test/Orleans.Serialization.UnitTests/Orleans.Serialization.UnitTests.csproj:55

  • The CopyNetStandardSerializationAsset target runs on every net10 build (including design-time builds) and always copies the asset, which can add noticeable overhead in IDE/design-time evaluation and repeated builds. Consider gating the target on DesignTimeBuild and setting SkipUnchangedFiles on the Copy task to avoid unnecessary work.

Copilot AI review requested due to automatic review settings September 4, 2026 02:32
@ReubenBond

Copy link
Copy Markdown
Member Author

AreAssemblyFilesAvailable treats a non-empty Assembly.Location as sufficient, but the file can still be missing/unavailable.

Addressed in bd21dabd2: the gate now uses File.Exists(assembly.Location), so dependency-context loading only runs when the selected assembly file is physically available. Added AssemblyFileAvailabilityIsFalseForMemoryLoadedAssembly; all 6 focused tests pass and netstandard2.1/net8/net10 builds succeed.

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.

Copilot review overview

🟢 Approval recommended

The changes are narrowly scoped, align with the PR’s stated single-file compatibility goals, and are backed by targeted unit tests covering the new behaviors and contracts.

Review tier: Lite
Findings: None

Copilot AI review requested due to automatic review settings September 4, 2026 03:06
@ReubenBond

Copy link
Copy Markdown
Member Author

The BVT failures were caused by AssemblyFileAvailabilityIsFalseForMemoryLoadedAssembly loading a second copy of the Orleans.Serialization.UnitTests assembly, which exposed duplicate generated metadata providers to later tests. Fixed in 36e0d82 by using a framework assembly with no Orleans application-part metadata for the memory-loaded probe. The full Orleans.Serialization.UnitTests BVT suite now passes: 4,050/4,050.

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.

Copilot review overview

🟡 Changes recommended

ReferencedAssemblyProvider.GetRelevantAssemblies() now calls AddAssembly, which currently results in infinite recursion/stack overflow due to the AddAssembly implementation.

Once you've addressed the issues Copilot identified, you can request another Copilot review.

Review tier: Lite
Findings: 1 High severity

New issues introduced by this change (1)
Severity Finding
High severity src/​Orleans.Serialization/​Hosting/​ReferencedAssemblyProvider.cs — GetRelevantAssemblies now calls AddAssembly, but AddAssembly currently calls itself…

Comment thread src/Orleans.Serialization/Hosting/ReferencedAssemblyProvider.cs
Copilot AI review requested due to automatic review settings September 4, 2026 03:14

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.

Copilot review overview

🟢 Approval recommended

The changes are cohesive, include appropriate analyzer annotations, and are backed by targeted tests covering the new single-file-safe behaviors.

Review tier: Lite
Findings: None

Issues resolved since last review (1)
Severity Finding
High severity src/​Orleans.Serialization/​Hosting/​ReferencedAssemblyProvider.cs — GetRelevantAssemblies now calls AddAssembly, but AddAssembly currently calls itself… View resolved comment

@ReubenBond
ReubenBond disabled auto-merge September 4, 2026 15:01
@ReubenBond
ReubenBond merged commit 8e7ad14 into dotnet:main Sep 4, 2026
141 of 143 checks passed
@ReubenBond
ReubenBond deleted the rb-fix-support-single-file-metadata branch September 4, 2026 15:01
@github-actions github-actions Bot locked and limited conversation to collaborators Oct 5, 2026
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.

2 participants