Conversation
…oadException on .NET Framework - Only register Task/Task<> eagerly in AwaitableFactory static init - Use FullName string checks + reflection/Activator for ValueTask provider creation - Update Mock.RaiseEvent to use runtime FullName checks for ValueTask too - Add regression test Issue1648 exercising TryGet(Task) + runtime VT simulation - Update changelog Tests and ildasm confirm cctor no longer contains ValueTask tokens.
…for cold-load isolation proof - Remove brittle AppDomain loader that failed on assembly identity. - Rely on ColdLoadVerifier.exe (separate exe, no VT tokens) + main TryGet asserts for verif plan step 4 proof. - Still exercises real shipped AwaitableFactory.TryGet directly. - Fresh successful COLD-LOAD-SUCCESS transcript captured in scratch.
… .NET FW - #if split: LegacyAwaitableFactory (net462/netstandard2.0) eagerly registers only Task/Task<>; ValueTask via FullName + deferred Activator (no typeof(ValueTask) in cctor or cold paths). - Modern (netstandard2.1+) AwaitableFactory is direct with no static cctor, isolated VT handling. - Committed standalone harness exe (Moq.Tests.Issue1648Harness) preloads 4.5.4, hooks resolve (throws real FileLoad on hit), does cold LoadFrom of Moq net462 + TryGet(Task) only. - Thin xunit test launches prebuilt harness under conflict and asserts on shipped TryGet; plus runtime IL guard for cctor. - Verification script for mechanical clean logs in mandated scratch. - Hard require for real older mismatch version; no fallbacks. Fixes #1648
Member
Author
🧪 Details on Microsoft Windows 10.0.26100❌ Moq.Tests.Regressions.IssueReportsFixture+Issue1648.AwaitableFactory_TryGet_for_Task_succeeds_without_premature_ValueTask_assembly_load
❌ Moq.Tests.Regressions.IssueReportsFixture+Issue1648.AwaitableFactory_TryGet_for_Task_succeeds_without_premature_ValueTask_assembly_load
from retest v1.1.0 on .NET 10.0.9 with 💜 by @devlooped |
…the #1648 regression - Ensures 'Harness exe not found' no longer happens on net472 test runs. - Test updated to strictly require the harness-dir ext (no arbitrary fallback).
…ile of committed driver) - Reference the harness project so net472 test builds produce the exe. - Fallback in Find uses CodeDom on the committed Program.cs when prebuilt layout not discoverable. - Strict require for ext from harness dir; version check. - Test still drives shipped code via the (prebuilt or temp compiled) driver exe.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to subscribe to this conversation on GitHub.
Already have an account?
Sign in.
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
This PR implements a reliable fix for #1648.
Problem
On .NET Framework / net462 / netstandard2.0, loading Moq could throw
FileLoadExceptionforSystem.Threading.Tasks.Extensionsv4.2.0.1+ atAwaitableFactory..cctor()if another dependency had preloaded a different version. Common (non-ValueTask) usage should succeed without binding redirects.Solution (per requested architecture)
#if NET462 || NETSTANDARD2_0split:LegacyAwaitableFactory: static cctor eagerly registers onlyTask/Task<>.FullNamestring checks + deferredasm.GetType("Moq.Async.ValueTask*")+Activator.AwaitableFactory): direct implementation, no static cctor,typeof(ValueTask)handling isolated behindNoInlininghelper so the coldTaskpath has no VT tokens. Minimal reflection only for our own generic factories.Verification (tests drive shipped code)
src/Moq.Tests.Issue1648Harness(net472 exe referencing exact 4.5.4 + ProjectRef to Moq net462).AssemblyResolvethat throws the real customerFileLoadExceptionon hit, does coldLoadFrom(moqPath)then reflectsTryGet(Task)/TryGet(Task<int>)only.IssueReportsFixturelaunches the prebuilt harness under conflict and asserts on the realAwaitableFactory.TryGetresults + exit code.scripts/verify-1648.ps1for mechanical clean evidence capture (>, no appends).All changes limited to
moq/src/**(plus the verification harness project and script as required for reliable proof). Targeted net472 tests + broad async filter pass. Cold-load proof (resolve count = 0 under mismatch) captured in mandated scratch.Fixes #1648