nunit3-vs-adapter icon indicating copy to clipboard operation
nunit3-vs-adapter copied to clipboard

v10 of Microsoft.* nugets makes it more difficult to support older nugets and runtime

Open SimonCropp opened this issue 1 month ago • 11 comments

i target System.ValueTuple to maintain support for older runtimes

    <PropertyGroup>
        <TargetFramework>net472</TargetFramework>
        <ImplicitUsings>enable</ImplicitUsings>
        <Nullable>enable</Nullable>
    </PropertyGroup>
    <ItemGroup>
        <PackageReference Include="Microsoft.NET.Test.Sdk" Version="18.0.1" />
        <PackageReference Include="NUnit" Version="4.4.0" />
        <PackageReference Include="NUnit3TestAdapter" Version="6.0.0" />
        <PackageReference Include="System.ValueTuple" Version="4.5.0" />
    </ItemGroup>

produces

 Error NU1605 : Warning As Error: Detected package downgrade: System.ValueTuple from 4.6.1 to 4.5.0. Reference the package directly from the project to select a different version. 
 ClassLibrary1 -> NUnit3TestAdapter 6.0.0 -> Microsoft.Extensions.DependencyModel 10.0.0 -> System.Text.Json 10.0.0 -> System.ValueTuple (>= 4.6.1) 
 ClassLibrary1 -> System.ValueTuple (>= 4.5.0)

SimonCropp avatar Dec 09 '25 09:12 SimonCropp

note that if i reference Microsoft.Extensions.DependencyModel directly i still the error

<Project Sdk="Microsoft.NET.Sdk">

    <PropertyGroup>
        <TargetFramework>net472</TargetFramework>
        <ImplicitUsings>enable</ImplicitUsings>
        <Nullable>enable</Nullable>
    </PropertyGroup>
    <ItemGroup>
        <PackageReference Include="Microsoft.NET.Test.Sdk" Version="18.0.1" />
        <PackageReference Include="NUnit" Version="4.4.0" />
        <PackageReference Include="NUnit3TestAdapter" Version="6.0.0" />
        <PackageReference Include="System.ValueTuple" Version="4.5.0" />
        <PackageReference Include="Microsoft.Extensions.DependencyModel" Version="6.0.2" />
    </ItemGroup>

</Project>
 Error NU1605 : Warning As Error: Detected package downgrade: Microsoft.Extensions.DependencyModel from 10.0.0 to 6.0.2. Reference the package directly from the project to select a different version. 
 ClassLibrary1 -> NUnit3TestAdapter 6.0.0 -> Microsoft.Extensions.DependencyModel (>= 10.0.0) 
 ClassLibrary1 -> Microsoft.Extensions.DependencyModel (>= 6.0.2)

SimonCropp avatar Dec 09 '25 09:12 SimonCropp

You can't downgrade versions. You must reference 4.6.1 as well.

Same for the DependencyModel, it must be version 10.0.0.

If the adapter depends on version 10 functionality, it cannot be given a lower version.

The only way to work around this is to not reference the adapter and use nunit-console to run the tests.

manfred-brands avatar Dec 09 '25 11:12 manfred-brands

@manfred-brands should this be added to the list of breaking changes in the release notes?

SimonCropp avatar Dec 09 '25 12:12 SimonCropp

A note would be appropriate. Most users wouldn't be affected, other when updating on dependency would also update versions of other packages.

@OsirisTerje Is the version 10 dictated by MS are can you do with a lower version.

manfred-brands avatar Dec 09 '25 12:12 manfred-brands

@manfred-brands @SimonCropp @CharliePoole The Microsoft.Extensions.DependencyModel is embedded with the engine, which require it. It is added as a dependency in the adapter, instead of copying the assembly from the engine. Copying the assembly doesn't sit quite well with me, it would probably give issues when the test project (or its dependencies) also depends on the Microsoft.Extensions.DependencyModel .

It could possible be downgraded to version 8, but that could cause issues with .net10 which seems to require an updated version of it.

The adapter could add a new target for .net 10, currently we have 462 and 8.0.

UPDATE: Looking at the engine, it doesn't require Microsoft.Extensions.DependencyModel for net framework, so the adapter should not depend on that for 462 either. That is one fix that can be done.

OsirisTerje avatar Dec 09 '25 13:12 OsirisTerje

@SimonCropp

The engine require version 8.0.2 (minimum) for .net8 and above. For net framework nothing.

So I have tested an alpha version of 6.0.1 with these fixes, and it works for @SimonCropp code above, and also for MTP, and tested for net462, net8 and net10.

Please verify the package (enclosed), and I'll push out a 6.0.1.

NUnit3TestAdapter.6.0.1-alpha.4.zip

OsirisTerje avatar Dec 09 '25 17:12 OsirisTerje

@OsirisTerje tried that nuget.

it caused a runtime error instead of a build error

  ----> System.IO.FileLoadException : Could not load file or assembly 'Microsoft.Extensions.Logging.Abstractions, Version=10.0.0.0, Culture=neutral, PublicKeyToken=adb9793829ddae60'. The requested assembly version conflicts with what is already bound in the app domain or specified in the manifest. (0x80131053)
  ----> System.IO.FileLoadException : Could not load file or assembly 'C:\Program Files\dotnet\shared\Microsoft.AspNetCore.App\10.0.1\Microsoft.Extensions.Logging.Abstractions.dll'. The requested assembly version conflicts with what is already bound in the app domain or specified in the manifest. (0x80131053)
--SetUp
   at System.Reflection.MethodBaseInvoker.InterpretedInvoke_Constructor(Object obj, IntPtr* args)

SimonCropp avatar Dec 09 '25 22:12 SimonCropp

I expected that, see my comments in the PR.

According to nuget the dependency was introduced between version 5.2.0 and 6.0.0, but none of the Microsoft.Testing.* packages depend on it. Ok, looking at the project.assets.json it is pulled in by the NUnit.Engine version 3.21.0 which seems to need it for the TestAssemblyResolver

@CharliePoole Was there a reason to increase the minimum version for the different target frameworks? The engine compiles fine if I use version 6.0.2 and all test pass.

Note that this specifies a minimum version only and as there is no upper bound set, it allows users to pick higher versions. As long as those are backwards compatible things should run fine.

manfred-brands avatar Dec 10 '25 01:12 manfred-brands

@manfred-brands It has been using 8.0.2 ever since we introduced the .NET 8.0 agent in version 3.19. It's possible that this is the first 3.x version >= 3.19 that the adapter has used.

As far as why... I think it's simply because it was the latest at the time. Until 3.21, the 6.0 agent used version 6.0.2 of this package an the 8.0 agent used 8.0.2. I think the significant change with 3.21 is that there is no longer a 6.0 build of the engine nor a 6.0 agent.

Are you suggesting we would be better off using the lowest version of the dependency that works for our tests, so as to avoid conflict with users? That might be a good idea for the future.

CharliePoole avatar Dec 10 '25 01:12 CharliePoole

@OsirisTerje tried that nuget.

it caused a runtime error instead of a build error

  ----> System.IO.FileLoadException : Could not load file or assembly 'Microsoft.Extensions.Logging.Abstractions, Version=10.0.0.0, Culture=neutral, PublicKeyToken=adb9793829ddae60'. The requested assembly version conflicts with what is already bound in the app domain or specified in the manifest. (0x80131053)
  ----> System.IO.FileLoadException : Could not load file or assembly 'C:\Program Files\dotnet\shared\Microsoft.AspNetCore.App\10.0.1\Microsoft.Extensions.Logging.Abstractions.dll'. The requested assembly version conflicts with what is already bound in the app domain or specified in the manifest. (0x80131053)
--SetUp
   at System.Reflection.MethodBaseInvoker.InterpretedInvoke_Constructor(Object obj, IntPtr* args)

Since you are targeting .NET Framework, you may need to use AutoGenerateBindingRedirects to get it to bind to the new versions. Particularly if you have transitive dependencies that target multiple versions of the assembly.

<PropertyGroup>
  <AutoGenerateBindingRedirects>true</AutoGenerateBindingRedirects>
</PropertyGroup>

This only works on net451 and higher, though. This setting also has no effect on .NET Core, but .NET Core is much better at allowing versions to be upgraded than .NET Framework.

That is the easy way and works in most cases. But if you need to drill deeper, see Could not load file or assembly...Oh my! How I went through five stages of grief and mastered assembly version conflict debugging with .NET CLI, ILSpy and Fusion Log.

NightOwl888 avatar Dec 10 '25 03:12 NightOwl888

@SimonCropp @CharliePoole @manfred-brands

The error happens with .net framework 472. In that version the adapter 6.0.1 doesn't include the Microsoft.Extensions.DependencyModel. So I would then assume the 472 project now works ?

The other crash with Microsoft.Extensions.Logging.Abstractions seems to be in an ASP.NET application, right ? It may match the #1371 from a colleague of me, so I have access to that code base. There is also another commenter reporting the same https://github.com/nunit/nunit3-vs-adapter/issues/1371#issuecomment-3636810831

So this is probably the major issue we're facing right now.

OsirisTerje avatar Dec 10 '25 19:12 OsirisTerje

@NightOwl888 @SimonCropp Works here with the latest alpha. Please check 6.0.1-alpha.6

OsirisTerje avatar Dec 19 '25 21:12 OsirisTerje