SIGN IN SIGN UP

CSHARP-6117: Consolidate target frameworks to net472, net6.0, net8.0 and net10.0 (#2089)

* CSHARP-6117: Consolidate target frameworks to net472, net6.0, net8.0 and net10.0

Replace netstandard2.1;net472;net6.0 with net472;net6.0;net8.0;net10.0. Drops
netstandard2.1, whose only remaining unique consumers were out of support
(.NET Core 3.1, .NET 5, Xamarin, standalone Mono) plus current Mono/IL2CPP
Unity, and adds first-class net8.0 and net10.0 assets. net6.0 is retained.

Test projects move to net6.0;net8.0;net10.0 (+net472 on Windows), dropping the
netcoreapp3.1 target that existed only to exercise the netstandard2.1 asset.
The SmokeTests consumer targets netcoreapp3.1 and net5.0 are removed, as no
supported asset applies to them.

Blocks the asset fallback that dropping netstandard2.1 would otherwise expose.
Removing the netstandard2.1 asset does not make those consumers fail: NuGet's
AssetTargetFallback silently hands any .NETStandard or pre-6.0 .NETCoreApp
project the net472 assets, reporting only warning NU1701, so the build succeeds
and then misbehaves at run time. MongoDB.Bson now ships an MSBuild check at
buildTransitive/netstandard2.0 that raises MONGO1001 for those frameworks.

That placement is load-bearing twice over. Because NuGet picks a package's
nearest compatible framework from the union of all asset groups, shipping a
buildTransitive asset at netstandard2.0 also makes the package directly
compatible with netstandard2.0, so AssetTargetFallback is never attempted for
lib and such a consumer resolves no assemblies at all. The net472 assets
therefore become structurally unselectable on .NET (Core) and .NET Standard,
not merely diagnosed, and there is deliberately no opt-out property: one could
suppress the message but could never restore a working net472 reference.

Compatibility is computed per package, though, so the guard in MongoDB.Bson does
not make its siblings compatible: they would still be handed lib/net472 through
AssetTargetFallback, with only NU1701 to show for it, and a consumer that treats
that warning as an error fails during restore before the guard's build-time error
can fire. MongoDB.Driver and MongoDB.Driver.Authentication.AWS therefore ship an
empty buildTransitive/netstandard2.0 asset group to opt out of the fallback the
same way. MongoDB.Driver.Encryption needs no placeholder, as its existing
build/MongoDB.Driver.Encryption.targets already makes it compatible with any
framework. The error itself is still raised in one place, by MongoDB.Bson.

The same placement suppresses NU1202 for the other netstandard2.0-compatible
frameworks that have no asset here (net461-net471, Xamarin, Tizen, UAP), so
those fail with a plain unresolved-type error instead. Accepted deliberately:
none is a supported target and none can bind the net472 assets either.

Polyfill package references are scoped to net472; all NETSTANDARD2_1 branches
are removed and the remaining conditionals normalised to NET6_0_OR_GREATER and
NET472, so the three modern assets expose an identical public surface.

Fixes three latent issues surfaced by the new targets:
- BsonClassMap used FormatterServices.GetUninitializedObject (obsolete as
  SYSLIB0050 from .NET 8), now RuntimeHelpers.GetUninitializedObject.
- ScramSha1/ScramSha256 used Rfc2898DeriveBytes constructors (obsolete as
  SYSLIB0060 from .NET 10), now the static Rfc2898DeriveBytes.Pbkdf2.
- The X509CertificateLoader test shim was guarded !NET8_0_OR_GREATER, but the
  BCL type arrived in .NET 9; corrected to !NET9_0_OR_GREATER.

Applies dotnet format to five test files. Their #if NET6_0_OR_GREATER regions
were never analysed before, because the first test target framework was
netcoreapp3.1, where that symbol is inactive; with net6.0 first they become
active and their pre-existing whitespace violations now fail the CSHARP-6147
format check. The changes are whitespace only.

Holds the Evergreen test matrix at its previous size. Swapping netstandard2.1 for
both net8.0 and net10.0 would have widened 26 variants by one framework each, so
net8.0 is dropped from them: every variant keeps net10.0 and net6.0, and the
Windows ones keep net472, leaving each at the count it had before. net8.0 is
still covered by the smoke tests, which ran six and five frameworks before and
now run four and three, by the unit tests, and by the performance tests. The
seven net8.0 task definitions this leaves unreferenced are removed with it.

Also gives net10.0 the full integration matrix in Evergreen, and fixes the
gcp KMS test case, which an #if NETCOREAPP3_0 that no target framework defines
had silently disabled.

Fixes run-ocsp-test, which alone among the six Evergreen functions that call
run-tests.sh never propagated FRAMEWORK. The ocsp tasks select net6.0 via
configure-framework, so only the 6.0 runtime is installed, but the empty
FRAMEWORK reaching execute-tests.sh dropped its -f argument and ran every target
framework of every test project, none of whose runtimes beyond 6.0 and the SDK's
own 10.0 are present. The gap predates this change and the netcoreapp3.1 leg
should have hit it too, but adding net8.0 certainly does: the testhost aborts for
want of an 8.0 runtime. Passing FRAMEWORK through also cuts each ocsp task to the
single framework it asks for.

NOTE: the test-analyzer task now passes TARGET_FRAMEWORK=net8.0 and requires a
matching change in mongodb/mongo-csharp-analyzer before it can pass.

* Review feedback
A
Arthur Vickers committed
871bb47ea02f55bbbace71022dcd5bcbde50c2f5
Parent: 1b7da30
Committed by GitHub <noreply@github.com> on 8/11/2026, 9:22:54 AM