Skip to content

[CLI] Fix loading analyzers that reference System.Composition on .NET 10 - #1831

Open
helgeu wants to merge 2 commits into
dotnet:mainfrom
helgeu:fix/1649-system-composition-net10
Open

[CLI] Fix loading analyzers that reference System.Composition on .NET 10#1831
helgeu wants to merge 2 commits into
dotnet:mainfrom
helgeu:fix/1649-system-composition-net10

Conversation

@helgeu

@helgeu helgeu commented Sep 2, 2026

Copy link
Copy Markdown
Contributor
  • I've read the contributing guide
  • Bug fixes / features have an issue, or new analyzers / refactorings / fixes were discussed first
  • Unit tests added for bug fixes / features (see note below)
  • Changelog updated
  • Build passes locally for net8.0, net9.0 and net10.0

Summary

roslynator analyze and fix crash on the first project when run on the .NET 10 SDK:

System.IO.FileNotFoundException: Could not load file or assembly
'System.Composition.AttributedModel, Version=10.0.0.10, ...'
   at Roslynator.AnalyzerAssembly.Load(...)   # while a code fix provider's attributes are read

Root cause

The compiler only loads diagnostic analyzers, whose attributes live in Microsoft.CodeAnalysis, so the SDK does not deploy System.Composition next to its analyzer / code-fix assemblies. Roslynator also inspects code fix providers, so reading their [ExportCodeFixProvider] / [Shared] attributes forces System.Composition.AttributedModel to load. The SDK analyzers are compiled against the SDK's copy, whose assembly version tracks the SDK patch level (10.0.0.10 here). Roslynator restores System.Composition transitively through Roslyn (9.0.0), so the higher-versioned reference cannot bind and the load fails.

This is the same class of problem as #1729 / #1783 (MSBuild): an assembly whose version moves independently of Roslynator's releases, so matching the version is not viable. Unlike MSBuild, there is no locator that resolves System.Composition, and the SDK does not place it next to the analyzers, so it cannot be resolved from the SDK either.

Fix

Redirect System.Composition.* to the copy shipped with the tool, ignoring the requested version. The public surface used by the analyzer / fixer attributes (Export, Shared, ImportingConstructor, ...) is stable across versions, and Roslynator only reflects over these attributes and instantiates the types with Activator, so the deployed copy is sufficient. An AssemblyLoadContext.Default.Resolving handler is registered at startup (.NET build only; the net48 build is unaffected).

Verification

  • Repro: roslynator analyze on a new net10.0 class library — before: crash; after: analyzers and fixers load and run (e.g. reports CS0219).
  • A real 9-project net10.0 solution — before: crash on project 1/9; after: all 9 projects analyze (1671 diagnostics reported).
  • Builds clean for net8.0, net9.0 and net10.0.

Note on tests

There is no CLI test project, and the behaviour is AssemblyLoadContext resolution that has no natural unit-test home (the analogous #1783 shipped without one). I verified it end to end as above and am happy to add a test if you prefer.

Related issue

Fixes #1649


Investigated and implemented with AI assistance (opencode).

The .NET 10 SDK ships analyzers and code fix providers that reference System.Composition but does not deploy System.Composition next to them. The version they were compiled against tracks the SDK patch level (for example 10.0.0.10) and is higher than the copy restored for the tool, so loading fixers failed with FileNotFoundException. Redirect System.Composition.* to the copy shipped with the tool, ignoring the requested version.
@helgeu
helgeu force-pushed the fix/1649-system-composition-net10 branch from 078a278 to e331730 Compare September 3, 2026 04:50
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

CLI not working on Linux

1 participant