Skip to content

Docs refresh for .NET 10, and make the interceptor goldens run outside Windows - #216

Merged
mgravell merged 3 commits into
mainfrom
docs-net10-and-crossplatform-goldens
Sep 11, 2026
Merged

mgravell merged 3 commits into
mainfrom
docs-net10-and-crossplatform-goldens

Conversation

@mgravell

Copy link
Copy Markdown
Member

Three tidies that turned up while re-reading the docs after a break. Separate commits; the middle one is a 100-file mechanical re-spelling, so it reads best commit-by-commit.

Docs: refresh for .NET 10 (ec6723c)

The getting-started transcripts were captured on the .NET 8 SDK and had aged out of accuracy - all re-captured against 10.0.302:

  • the MSBuild version 17.8.3+195e7f5a3 for .NET banner is no longer printed;
  • CS9137 no longer calls interceptors an experimental feature;
  • the generated-file path in that error was missing its obj\Debug\<tfm> segment;
  • sample output said net8.0, where UsageLinker has targeted net10.0 for a while.

The part worth a look. #215 moved the docs to InterceptorsNamespaces, which is right for current SDKs but only half the story - the .NET 8 SDK, which this page names as the minimum, understands only InterceptorsPreviewNamespaces, and neither SDK knows the other's name:

SDK InterceptorsPreviewNamespaces InterceptorsNamespaces both
8.0.423 ❌ CS9137
10.0.302

Both are now shown in one annotated snippet, with a FAQ entry for the symptom, since CS9137 is what people actually arrive with. UsageLinker and Dapper.AOT.Test set only the older name; they now set both, as UsageBenchmark already did.

Also: a PublishAot section (the page never mentioned it, despite that being the point); the limitations section now points at declarative type handlers rather than a flat "configuration is not used"; the FAQ's QueryMultiple answer no longer implies it is supported, since it is refused and diagnosed; EmitCompilerGeneratedFiles offered for viewing generated code outside VS; and two bulk-copy fixes - the MS Learn link pointed at legacy System.Data.SqlClient, and the ColumnMappings sample was missing a comma, so it would not compile.

Tests: goldens are OS-neutral (1450fa4)

Tests find their inputs with Directory.GetFiles, and that path is baked into the emitted [InterceptsLocation(...)] - so the goldens carried whatever separator wrote them. All 49 interceptor golden tests failed on Linux; nobody had noticed, because nobody had run them there.

RoslynTestHelpers.CreateCompilation now normalizes to / before it reaches the compilation - which is what GeneratorTestBase already did for the .output.txt diagnostics side ("need to normalize paths"); the code-golden side was simply the half that got missed.

Two spots that are easy to miss: IncludeSqlSource also embeds the path in a SQL comment, so its netfx golden needed it too; and SqliteUsage.snapshot.cs is deliberately untouched, being a real interceptor compiled into the test assembly whose InterceptsLocation is the /_/ deterministic path.

Tests: golden write-back actually works now (52b6022)

InterceptorTests writes .output.cs back to source "for git tracking", but located the source folder via [CallerFilePath], which DeterministicSourcePaths maps to /_/test/.... The write failed on every OS, silently - the exception is caught and logged, so the only symptom was a "Could not find a part of the path" line and a golden that never updated. notes/harness-baseline.md carried a manual workaround for this.

GeneratorTestBase.ProjectFolder walks up from the test binaries to find the project file instead: determinism intact, no absolute paths baked into the assembly, and null off a working tree so CI doesn't write.

Verification

net8.0 376/376 and net10.0 376/376, both from 327/376. A run leaves the working tree unchanged, which also confirms the two legs agree on the shared goldens. The note records the gotcha that cost me a confusing diagnosis: the expected side is read from the copy in bin, so after a golden changes you need a build before the next run agrees with it.

net48 cannot run here and wants a Windows check - its goldens got the identical mechanical treatment, and normalization happens before the generator sees anything so the TFM is irrelevant to the path string, but it is unverified.

The build transcripts were captured on the .NET 8 SDK and had aged out of accuracy:
the `MSBuild version 17.8.3+195e7f5a3 for .NET` banner is no longer printed, CS9137
no longer calls interceptors an *experimental* feature, the generated-file path in
that error is missing its `obj\Debug\<tfm>` segment, and the sample output still
said net8.0 where `UsageLinker` has targeted net10.0 for a while. All re-captured.

#215 moved the docs to `InterceptorsNamespaces`, which is right for current SDKs but
only half the story: the .NET 8 SDK - which this page names as the minimum - knows
only `InterceptorsPreviewNamespaces`, and neither SDK understands the other's name.
Both are now shown in one snippet, annotated, with the rule spelled out and a FAQ
entry for the symptom, since CS9137 is what people actually arrive with.

`UsageLinker` and `Dapper.AOT.Test` set only the older name; they now set both, as
`UsageBenchmark` already did, so the samples match the advice.

Also: a section on `PublishAot`, which the page never mentioned despite being the
point of the exercise; the limitations section now points at the declarative type
handlers instead of a flat "configuration is not used"; the FAQ's `QueryMultiple`
answer no longer implies it is supported (it is refused, and diagnosed); and
`EmitCompilerGeneratedFiles` is offered for viewing generated code outside VS.

Bulk copy: the MS Learn link pointed at the legacy `System.Data.SqlClient` type, and
the `ColumnMappings` sample was missing a comma, so it would not compile.
`InterceptorTests` and `AccessorInterceptorTests` find their inputs with
`Directory.GetFiles`, and that path is baked into the emitted
`[InterceptsLocation(...)]` - so the checked-in goldens carried whatever separator
the machine that wrote them used. They were only ever written on Windows, so all 49
interceptor golden tests failed on Linux; nobody had noticed, because nobody had run
them there.

`RoslynTestHelpers.CreateCompilation` now normalizes the path to `/` before it
reaches the compilation, which is what `GeneratorTestBase` already did for the
`.output.txt` diagnostics side ("need to normalize paths") - the code-golden side was
simply the half that got missed. The goldens are re-spelled to match.

Note `IncludeSqlSource`, where the path also appears inside a SQL comment, so its
netfx golden needed the same change; and `SqliteUsage.snapshot.cs`, which is left
alone deliberately - it is a real interceptor compiled into the test assembly, and
its `InterceptsLocation` is the `/_/` path that `DeterministicSourcePaths` produces.
`InterceptorTests` writes `.output.cs` back to source "for git tracking", but it
located the source folder via `[CallerFilePath]` - which the project's
`DeterministicSourcePaths` maps to `/_/test/...`. The write therefore failed on every
OS, silently: the exception is caught and logged, so the only symptom was a "Could
not find a part of the path" line in the test output and a golden that never updated.
`notes/harness-baseline.md` carried a manual workaround for this.

`GeneratorTestBase.ProjectFolder` walks up from the test binaries to find the project
file instead. That keeps determinism - and therefore the checked-in
`SqliteUsage.snapshot.cs`, whose `InterceptsLocation` is the `/_/` path - and returns
null when there is no working tree, so CI simply doesn't write. `GetOriginCodeLocation`
had no other callers and is removed.

The note is updated for both this and the separator fix, including the gotcha that
cost me a confusing diagnosis: the *expected* side is read from the copy in `bin`, so
after a golden changes a build is needed before the next run agrees with it.

net8.0 and net10.0 are now 376/376 (were 327/376), and a run leaves the tree
unchanged - which also confirms the two legs agree on the shared goldens. net48
cannot run here and wants a Windows check.
@mgravell
mgravell merged commit e485dc2 into main Sep 11, 2026
2 checks passed
mgravell added a commit that referenced this pull request Sep 11, 2026
`state-of-play.md` is the "read first after a break" page and was the most wrong
thing in the repo: it still listed #206/#207/#208 as in flight with a landing order
to follow, and knew nothing of #209-#216. It now says what is true - nothing of ours
in flight, the four open PRs are all external and all awaiting a decision.

It also absorbs the account of **why #206 was closed**, which was sitting unmerged on
the `typehandler-registration-note` branch and existed nowhere in main: gating stopped
the bridge emitting for consumers who did not opt in, but the read-side check still
sat in `RowFactory.GetValue<T>` - the type-flexible arm of every mapped member - so
everyone paid for a feature almost nobody would enable. The emission-time fix that
was considered and rejected is recorded with it, since that is the part most likely
to be re-proposed.

Two things promoted, because they gate real work and were buried:

- the behavioural harness is local-only and does **not** exist on this machine (no
  `aot-harness` branch, no SQL Server, Windows-shaped repack recipe), so no phase-3
  round can be closed and 677/793 cannot be re-measured until it is rebuilt;
- net48 is unverified since #216 and #214, both of which changed interceptor goldens.

Corrections: #117 and #162 are closed, not awaiting a decision; the `type-handler`
branch harvest was filed as "before #208 settles", and #208 has settled; diagnostic
ids as actually shipped (DAP053-056, next free DAP057).

`parity.md`: the `CommandDefinition` row still said "27 overloads, every one skipped
silently" - #214 moved the `Type`+`CommandDefinition` combinations out, so it is 21
of the 22 in that bucket. Cites the report rather than restating a number, which is
what #213 was for.

Also: `typehandlers-design.md` never existed in main - it was a file on the closed
#206 branch - leaving dangling links in three notes. Pointed at the note that did
land, `typehandler-registration.md`.
@mgravell
mgravell deleted the docs-net10-and-crossplatform-goldens branch September 11, 2026 13:34
mgravell added a commit that referenced this pull request Sep 11, 2026
The job already runs on windows-latest and *builds* net48, so a compile break there
would be caught - but the only test steps are net8.0 and net10.0. That gap matters
specifically because the `*.output.netfx.*` interceptor goldens are compared at
**test** time: a netfx golden can be wrong while CI stays green, which is exactly the
state #214, #216 and #220 have left main in (all three touched those files, and none
of them could be exercised on Linux).

One more step, same job, same image, same filter.
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.

1 participant