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

Calling the compiler with analyzers which reference different versions of the same assembly results in FileLoadException #41421

Open
costin-zaharia-sonarsource opened this issue Feb 5, 2020 · 1 comment

Comments

@costin-zaharia-sonarsource

Version Used:

  • Microsoft (R) Visual C# Compiler version 3.4.1-beta4-19614-01 (1650460)
  • Microsoft (R) Visual C# Compiler version 2.3.2.61921 (ad0efbb)

Steps to Reproduce:

  1. Have 2 analyzers which are referencing different versions of the same assembly
  2. Call the compiler passing the analyzers and the dependencies

dotnet "C:\Program Files\dotnet\sdk\3.1.101\Roslyn\bincore\csc.dll" Program.cs /r:"%localappdata%\NuGet\microsoft.netcore.app\2.0.0\ref\netcoreapp2.0\System.Runtime.dll" /analyzer:"FirstAnalyzer\FirstAnalyzer\FirstAnalyzer\bin\Debug\netstandard2.0\FirstAnalyzer.dll" /analyzer:"FirstAnalyzer\FirstAnalyzer\FirstAnalyzer\bin\Debug\netstandard2.0\Common.dll" /analyzer:"SecondAnalyzer\SecondAnalyzer\SecondAnalyzer\bin\Debug\netstandard2.0\SecondAnalyzer.dll" /analyzer:"SecondAnalyzer\SecondAnalyzer\SecondAnalyzer\bin\Debug\netstandard2.0\Common.dll"

A reproducer can be found here: https://github.com/costin-zaharia-sonarsource/dotnet-core-analyzer-dependency-load/tree/master/src and running the build will also generate a file (debug-output.txt) with the loaded assemblies:

On .Net core both analyzers will load the same assembly version:

First assembly loaded: Common, Version=2.0.0.0, Culture=neutral, PublicKeyToken=2fe0417f313f4af7
Second assembly loaded: Common, Version=2.0.0.0, Culture=neutral, PublicKeyToken=2fe0417f313f4af7

on .Net Framework each analyzer will load both versions:

First assembly loaded: Common, Version=2.0.0.0, Culture=neutral, PublicKeyToken=2fe0417f313f4af7
Second assembly loaded: Common, Version=2.0.0.0, Culture=neutral, PublicKeyToken=2fe0417f313f4af7
First assembly loaded: Common, Version=2.2.0.0, Culture=neutral, PublicKeyToken=2fe0417f313f4af7
Second assembly loaded: Common, Version=2.2.0.0, Culture=neutral, PublicKeyToken=2fe0417f313f4af7

Expected Behavior:
Each analyzer will load the correct version of the dependency and no exception is raised.

This seems to be handled correctly on .Net Framework.

Actual Behavior:
warning AD0001: Analyzer 'SecondAnalyzer.SecondAnalyzerAnalyzer' threw an exception of type 'System.IO.FileLoadException' with message 'Could not load file or assembly 'Common, Version=2.2.0.0, Culture=neutral, PublicKeyToken=2fe0417f313f4af7'. Could not find or load a specific file. (0x80131621)'.

Additional notes:
the order in which the analyzers are passed to the compiler matters. Using this: /analyzer:"lib\first\Common.dll" /analyzer:"lib\second\SecondAnalyzer.dll" /analyzer:"lib\first\FirstAnalyzer.dll" /analyzer:"lib\second\Common.dll" will make the Version 2.2.0.0 load first and not raise the exception.

Work around:
pack all the dependencies with a tool like https://github.com/dotnet/ILMerge

@andrei-epure-sonarsource

We've been pointed to using directory-scoped Assembly Load Contexts to fix this (see #55098 and #56442 (comment)).

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

3 participants