Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Project with Moq and explicit dependency on higher System.Threading.Tasks.Extension throw exception!! #873

Closed
basprins opened this issue Aug 7, 2019 · 4 comments

Comments

@basprins
Copy link

basprins commented Aug 7, 2019

Hi,

We have a (severe) issue with Moq and I hope you can help us out. A little background:
We use our own private nuget repository so that we have control over which packages are used throughout the project.
We have nuget packages that depend on System.Threading.Tasks.Extensions 4.5.3.
We don't want to mix versions in our output folder, so everywhere where we have dependencies on System.Threading.Tasks.Extensions, we add a top-level explicit reference to the version we have available.

This results in:
[anyunittestproject]
dependency on Moq
dependency on System.Threading.Tasks.Extensions 4.5.3

This should be allowed, as Moq nuget package claims:
System.Threading.Tasks.Extensions (>= 4.5.1)

But, when we do this, we get the following runtime exception:

System.TypeInitializationException : The type initializer for 'Moq.DefaultValueProvider' threw an exception.
----> System.IO.FileLoadException : Could not load file or assembly 'System.Threading.Tasks.Extensions, Version=4.2.0.0, Culture=neutral, PublicKeyToken=cc7b13ffcd2ddd51' or one of its dependencies. The located assembly's manifest definition does not match the assembly reference. (Exception from HRESULT: 0x80131040)
at Moq.Mock`1..ctor(MockBehavior behavior, Object[] args) in C:\projects\moq4\src\Moq\Mock.Generic.cs:line 112

I made a really simple reproducing example here:

https://github.com/basprins/moqissue

Could you please let me know:

  • if you agree that it's an issue
  • if there is a fix possible
  • if there will be time in the near future to address the issue

Many thanks in advance!

@basprins
Copy link
Author

basprins commented Aug 7, 2019

I cloned the moq4 repo and updated the extensions dependency to 4.5.3 myself, created a new nuget and tested it. That works fine. Not sure if that helps in understanding what the issue is, but for me it's a perfect quick hack for now :)

@stakx
Copy link
Contributor

stakx commented Aug 7, 2019

if you agree that it's an issue

It is an issue, but with your project setup, not Moq. Between the two versions of the System.Threading.Tasks.Extensions NuGet package, Microsoft changed the assembly version from 4.2.0.0 to 4.2.0.1 (which they probably shouldn't have done if they considered the sanity of people who are still on the .NET Framework). Moq is referencing version 4.2.0.0, while your project is forcing 4.2.0.1... and you don't have an assembly binding redirect in place.

(To be honest, I don't see why the .NET Framework is that picky even about the patch version number; that's ridiculous, but that's how it appears to work.)

if there is a fix possible

Quite frankly, the easiest fix would be to convert your test project file from the old .csproj format to the new SDK-style format. For example:

<Project Sdk="Microsoft.NET.Sdk">
  <PropertyGroup>
    <OutputType>Library</OutputType>
    <TargetFramework>net472</TargetFramework>
    <!-- The following should be added automatically by the SDK, but let's be extra careful
         and add them ourselves: -->
    <AutoGenerateBindingRedirects>true</AutoGenerateBindingRedirects>
    <GenerateBindingRedirectsOutputType>true</GenerateBindingRedirectsOutputType>
  </PropertyGroup>
  <ItemGroup>
    <PackageReference Include="Moq" Version="4.10.1"/>
    <PackageReference Include="NUnit" Version="3.10.1"/>
    <PackageReference Include="System.Threading.Tasks.Extensions" Version="4.5.3"/>
    <!-- added by me, without this or the NUnit console runner, I couldn't run your tests: -->
    <PackageReference Include="NUnit3TestAdapter" Version="3.13.0"/>
  </ItemGroup>
</Project>

if there will be time in the near future to address the issue

No, this problem needs to be solved in client projects (e.g. as above), not in Moq. I'll eventually update Moq's package dependencies, but I don't see that as a particularly urgent task.

@stakx stakx closed this as completed Aug 7, 2019
@basprins
Copy link
Author

basprins commented Aug 7, 2019

Hi stakx! Thanks a bunch for the quick response and for explaining the actual root cause!

Rather stupid indeed that microsoft changes assembly versions for, if I understand you correctly, no reason at all...

But, I will try this tomorrow morning. Thanks again! Great help!

PS: I use the resharper test runner, so that's why you needed to add the nunit test runner.

@stakx
Copy link
Contributor

stakx commented Aug 7, 2019

Hi stakx! Thanks a bunch [...]

You're welcome. Hope I could help.

Rather stupid indeed that microsoft changes assembly versions for, if I understand you correctly, no reason at all...

Well, it depends. Before NuGet, there was actually a point to versioning assemblies via [AssemblyVersion]. (You could put several versions of such assemblies in the GAC.) But since NuGet, the .NET Framework's assembly version binding policy mostly just interferes with NuGet's only semver version selection, so some people have figured out that NuGet should be in the driver's seat. You then neutralize .NET assembly version binding e.g. by only setting the major (and/or minor) version but leaving everything else at 0, so minor version changes won't require binding redirects.

Not sure why Microsoft occasionally makes such changes to assembly versions.

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

No branches or pull requests

2 participants