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

fix-analyzers throwing error. #734

Closed
ChrisBertrand opened this issue Jul 17, 2020 · 13 comments
Closed

fix-analyzers throwing error. #734

ChrisBertrand opened this issue Jul 17, 2020 · 13 comments
Assignees
Labels
Bug This issue describes behavior that is not working as expected
Milestone

Comments

@ChrisBertrand
Copy link

ChrisBertrand commented Jul 17, 2020

When running the latest development build. --version 5.0.136601

It runs through until it hits, Running Formatters then throws an error. Fix-style is working fine.

Running formatters.
Unhandled exception: System.IO.FileLoadException: Assembly with same name is already loaded
at System.Runtime.Loader.AssemblyLoadContext.LoadFromPath(IntPtr ptrNativeAssemblyLoadContext, String ilPath, String niPath, ObjectHandleOnStack retAssembly)
at System.Runtime.Loader.AssemblyLoadContext.LoadFromAssemblyPath(String assemblyPath)
at System.Reflection.Assembly.LoadFrom(String assemblyFile)
at Microsoft.CodeAnalysis.Tools.Analyzers.AnalyzerReferenceInformationProvider.<>c.b__0_1(String path) in /_/src/Analyzers/AnalyzerReferenceInformationProvider.cs:line 28

The full set of analyzers returned are:

[0]: ".nuget\\packages\\microsoft.entityframeworkcore.analyzers\\3.1.4\\analyzers\\dotnet\\cs\\Microsoft.EntityFrameworkCore.Analyzers.dll"
    [1]: "packages\\Microsoft.CodeAnalysis.VersionCheckAnalyzer.2.9.6\\analyzers\\dotnet\\cs\\Microsoft.CodeAnalysis.VersionCheckAnalyzer.resources.dll"
    [2]: "packages\\Microsoft.CodeAnalysis.VersionCheckAnalyzer.2.9.6\\analyzers\\dotnet\\Microsoft.CodeAnalysis.VersionCheckAnalyzer.dll"
    [3]: "packages\\Microsoft.CodeQuality.Analyzers.2.9.6\\analyzers\\dotnet\\cs\\Humanizer.dll"
    [4]: "packages\\Microsoft.CodeQuality.Analyzers.2.9.6\\analyzers\\dotnet\\cs\\Microsoft.CodeQuality.Analyzers.dll"
    [5]: "packages\\Microsoft.CodeQuality.Analyzers.2.9.6\\analyzers\\dotnet\\cs\\Microsoft.CodeQuality.CSharp.Analyzers.dll"
    [6]: "packages\\Microsoft.NetCore.Analyzers.2.9.6\\analyzers\\dotnet\\cs\\Microsoft.NetCore.Analyzers.dll"
    [7]: "packages\\Microsoft.NetCore.Analyzers.2.9.6\\analyzers\\dotnet\\cs\\Microsoft.NetCore.CSharp.Analyzers.dll"
    [8]: "packages\\Microsoft.NetFramework.Analyzers.2.9.6\\analyzers\\dotnet\\cs\\Microsoft.NetFramework.Analyzers.dll"
    [9]: "packages\\Microsoft.NetFramework.Analyzers.2.9.6\\analyzers\\dotnet\\cs\\Microsoft.NetFramework.CSharp.Analyzers.dll"
    [10]: "C:\\Program Files\\dotnet\\sdk\\3.1.301\\Sdks\\Microsoft.NET.Sdk.Web\\analyzers\\cs\\Microsoft.AspNetCore.Analyzers.dll"
    [11]: "C:\\Program Files\\dotnet\\sdk\\3.1.301\\Sdks\\Microsoft.NET.Sdk.Web\\analyzers\\cs\\Microsoft.AspNetCore.Mvc.Analyzers.dll"
    [12]: "C:\\Program Files\\dotnet\\sdk\\3.1.301\\Sdks\\Microsoft.NET.Sdk.Web\\analyzers\\cs\\Microsoft.AspNetCore.Components.Analyzers.dll"
    [13]: ".nuget\\packages\\microsoft.codeanalysis.analyzers\\2.9.4\\analyzers\\dotnet\\cs\\Microsoft.CodeAnalysis.Analyzers.dll"
    [14]: ".nuget\\packages\\microsoft.codeanalysis.analyzers\\2.9.4\\analyzers\\dotnet\\cs\\Microsoft.CodeAnalysis.CSharp.Analyzers.dll"
    [15]: ".nuget\\packages\\microsoft.entityframeworkcore.analyzers\\3.1.4\\analyzers\\dotnet\\cs\\Microsoft.EntityFrameworkCore.Analyzers.dll"
    [16]: ".nuget\\packages\\microsoft.codeanalysis.analyzers\\2.9.4\\analyzers\\dotnet\\cs\\Microsoft.CodeAnalysis.Analyzers.dll"
    [17]: ".nuget\\packages\\microsoft.codeanalysis.analyzers\\2.9.4\\analyzers\\dotnet\\cs\\Microsoft.CodeAnalysis.CSharp.Analyzers.dll"
    [18]: ".nuget\\packages\\microsoft.entityframeworkcore.analyzers\\3.1.4\\analyzers\\dotnet\\cs\\Microsoft.EntityFrameworkCore.Analyzers.dll"
    [19]: ".nuget\\packages\\xunit.analyzers\\0.10.0\\analyzers\\dotnet\\cs\\xunit.analyzers.dll"
    [20]: ".nuget\\packages\\microsoft.entityframeworkcore.analyzers\\3.1.4\\analyzers\\dotnet\\cs\\Microsoft.EntityFrameworkCore.Analyzers.dll"
    [21]: ".nuget\\packages\\microsoft.entityframeworkcore.analyzers\\3.1.4\\analyzers\\dotnet\\cs\\Microsoft.EntityFrameworkCore.Analyzers.dll"
    [22]: ".nuget\\packages\\xunit.analyzers\\0.10.0\\analyzers\\dotnet\\cs\\xunit.analyzers.dll"
    [23]: "C:\\Program Files\\dotnet\\sdk\\3.1.301\\Sdks\\Microsoft.NET.Sdk.Web\\analyzers\\cs\\Microsoft.AspNetCore.Analyzers.dll"
    [24]: "C:\\Program Files\\dotnet\\sdk\\3.1.301\\Sdks\\Microsoft.NET.Sdk.Web\\analyzers\\cs\\Microsoft.AspNetCore.Mvc.Analyzers.dll"
    [25]: "C:\\Program Files\\dotnet\\sdk\\3.1.301\\Sdks\\Microsoft.NET.Sdk.Web\\analyzers\\cs\\Microsoft.AspNetCore.Components.Analyzers.dll"
    [26]: ".nuget\\packages\\microsoft.aspnetcore.components.analyzers\\3.1.3\\analyzers\\dotnet\\cs\\Microsoft.AspNetCore.Components.Analyzers.dll"
    [27]: ".nuget\\packages\\microsoft.codeanalysis.analyzers\\2.9.4\\analyzers\\dotnet\\cs\\Microsoft.CodeAnalysis.Analyzers.dll"
    [28]: ".nuget\\packages\\microsoft.codeanalysis.analyzers\\2.9.4\\analyzers\\dotnet\\cs\\Microsoft.CodeAnalysis.CSharp.Analyzers.dll"
    [29]: ".nuget\\packages\\microsoft.entityframeworkcore.analyzers\\3.1.4\\analyzers\\dotnet\\cs\\Microsoft.EntityFrameworkCore.Analyzers.dll"
    [30]: ".nuget\\packages\\xunit.analyzers\\0.10.0\\analyzers\\dotnet\\cs\\xunit.analyzers.dll"
    [31]: ".nuget\\packages\\xunit.analyzers\\0.10.0\\analyzers\\dotnet\\cs\\xunit.analyzers.dll"
    [32]: ".nuget\\packages\\microsoft.aspnetcore.components.analyzers\\3.1.3\\analyzers\\dotnet\\cs\\Microsoft.AspNetCore.Components.Analyzers.dll"
    [33]: ".nuget\\packages\\microsoft.codeanalysis.analyzers\\2.9.4\\analyzers\\dotnet\\cs\\Microsoft.CodeAnalysis.Analyzers.dll"
    [34]: ".nuget\\packages\\microsoft.codeanalysis.analyzers\\2.9.4\\analyzers\\dotnet\\cs\\Microsoft.CodeAnalysis.CSharp.Analyzers.dll"
    [35]: ".nuget\\packages\\microsoft.entityframeworkcore.analyzers\\3.1.4\\analyzers\\dotnet\\cs\\Microsoft.EntityFrameworkCore.Analyzers.dll"
    [36]: ".nuget\\packages\\xunit.analyzers\\0.10.0\\analyzers\\dotnet\\cs\\xunit.analyzers.dll"
    [37]: ".nuget\\packages\\microsoft.entityframeworkcore.analyzers\\3.1.4\\analyzers\\dotnet\\cs\\Microsoft.EntityFrameworkCore.Analyzers.dll"
    [38]: ".nuget\\packages\\xunit.analyzers\\0.10.0\\analyzers\\dotnet\\cs\\xunit.analyzers.dll"
    [39]: ".nuget\\packages\\microsoft.entityframeworkcore.analyzers\\3.1.5\\analyzers\\dotnet\\cs\\Microsoft.EntityFrameworkCore.Analyzers.dll"
    [40]: ".nuget\\packages\\xunit.analyzers\\0.10.0\\analyzers\\dotnet\\cs\\xunit.analyzers.dll"
    [41]: ".nuget\\packages\\microsoft.aspnetcore.components.analyzers\\3.1.3\\analyzers\\dotnet\\cs\\Microsoft.AspNetCore.Components.Analyzers.dll"

And the distinct list:

    [0]: ".nuget\\packages\\microsoft.entityframeworkcore.analyzers\\3.1.4\\analyzers\\dotnet\\cs\\Microsoft.EntityFrameworkCore.Analyzers.dll"
    [1]: packages\\Microsoft.CodeAnalysis.VersionCheckAnalyzer.2.9.6\\analyzers\\dotnet\\cs\\Microsoft.CodeAnalysis.VersionCheckAnalyzer.resources.dll"
    [2]: packages\\Microsoft.CodeAnalysis.VersionCheckAnalyzer.2.9.6\\analyzers\\dotnet\\Microsoft.CodeAnalysis.VersionCheckAnalyzer.dll"
    [3]: packages\\Microsoft.CodeQuality.Analyzers.2.9.6\\analyzers\\dotnet\\cs\\Humanizer.dll"
    [4]: packages\\Microsoft.CodeQuality.Analyzers.2.9.6\\analyzers\\dotnet\\cs\\Microsoft.CodeQuality.Analyzers.dll"
    [5]: packages\\Microsoft.CodeQuality.Analyzers.2.9.6\\analyzers\\dotnet\\cs\\Microsoft.CodeQuality.CSharp.Analyzers.dll"
    [6]: packages\\Microsoft.NetCore.Analyzers.2.9.6\\analyzers\\dotnet\\cs\\Microsoft.NetCore.Analyzers.dll"
    [7]: packages\\Microsoft.NetCore.Analyzers.2.9.6\\analyzers\\dotnet\\cs\\Microsoft.NetCore.CSharp.Analyzers.dll"
    [8]: packages\\Microsoft.NetFramework.Analyzers.2.9.6\\analyzers\\dotnet\\cs\\Microsoft.NetFramework.Analyzers.dll"
    [9]: packages\\Microsoft.NetFramework.Analyzers.2.9.6\\analyzers\\dotnet\\cs\\Microsoft.NetFramework.CSharp.Analyzers.dll"
    [10]: "C:\\Program Files\\dotnet\\sdk\\3.1.301\\Sdks\\Microsoft.NET.Sdk.Web\\analyzers\\cs\\Microsoft.AspNetCore.Analyzers.dll"
    [11]: "C:\\Program Files\\dotnet\\sdk\\3.1.301\\Sdks\\Microsoft.NET.Sdk.Web\\analyzers\\cs\\Microsoft.AspNetCore.Mvc.Analyzers.dll"
    [12]: "C:\\Program Files\\dotnet\\sdk\\3.1.301\\Sdks\\Microsoft.NET.Sdk.Web\\analyzers\\cs\\Microsoft.AspNetCore.Components.Analyzers.dll"
    [13]: ".nuget\\packages\\microsoft.codeanalysis.analyzers\\2.9.4\\analyzers\\dotnet\\cs\\Microsoft.CodeAnalysis.Analyzers.dll"
    [14]: ".nuget\\packages\\microsoft.codeanalysis.analyzers\\2.9.4\\analyzers\\dotnet\\cs\\Microsoft.CodeAnalysis.CSharp.Analyzers.dll"
    [15]: ".nuget\\packages\\xunit.analyzers\\0.10.0\\analyzers\\dotnet\\cs\\xunit.analyzers.dll"
    [16]: ".nuget\\packages\\microsoft.aspnetcore.components.analyzers\\3.1.3\\analyzers\\dotnet\\cs\\Microsoft.AspNetCore.Components.Analyzers.dll"
    [17]: ".nuget\\packages\\microsoft.entityframeworkcore.analyzers\\3.1.5\\analyzers\\dotnet\\cs\\Microsoft.EntityFrameworkCore.Analyzers.dll"
@jmarolf
Copy link
Contributor

jmarolf commented Jul 17, 2020

hmm, we may need to add some more complex logic to handle duplicate analyzer assemblies being loaded.

@Youssef1313
Copy link
Member

@jmarolf Wouldn't a try with catch FileLoadException be enough?
I know it's not really a good solution, but an easy workaround.

@jmarolf
Copy link
Contributor

jmarolf commented Jul 24, 2020

I guess the question is: What does the user want us to do? There are two different analyzers at play which may find different issues. try/catching just means the behavior for format is non-deterministic

@sharwell
Copy link
Member

Which analyzer is failing?

@sharwell
Copy link
Member

Since we can't load analyzers side-by-side on .NET Core (and we know dotnet-format is running on .NET Core, we should be using an assembly load context for the analyzers which allows them to be loaded even when there is more than one analyzer with the same name in the solution.

@jmarolf
Copy link
Contributor

jmarolf commented Jul 24, 2020

I agree that assembly load context is likely the going to be the correct solution here

@Youssef1313
Copy link
Member

I'm not very familiar with dynamic assembly loading. But is using AssemblyLoadContext is to replace:

            var assemblies = solution.Projects
                .SelectMany(project => project.AnalyzerReferences.Select(reference => reference.FullPath))
                .Distinct()
                .Select(path => Assembly.LoadFrom(path));

with

            var context = new AssemblyLoadContext();
            var assemblies = solution.Projects
                .SelectMany(project => project.AnalyzerReferences.Select(reference => reference.FullPath))
                .Distinct()
                .Select(path => context.LoadFromAssemblyPath(path));

or I'm misunderstanding things?

@sharwell
Copy link
Member

sharwell commented Jul 24, 2020

The easiest way would be either one ALC for each analyzer directory, or one ALC for each project.

Going by analyzer directory puts the most power in the hands of each analyzer author to prepare a package with the necessary dependencies.

@jmarolf
Copy link
Contributor

jmarolf commented Jul 24, 2020

One per project is likely the correct design moving forward

@Youssef1313
Copy link
Member

@jmarolf, Something like that?

            var assemblies = new HashSet<Assembly>();
            foreach (var project in solution.Projects)
            {
                var context = new AssemblyLoadContext();
                set.AddRange(project.AnalyzerReferences.Select(reference => context.LoadFromAssemblyPath(reference.FullPath)));
            }

            return AnalyzerFinderHelpers.LoadAnalyzersAndFixers(assemblies);

@ChrisBertrand
Copy link
Author

One per project is likely the correct design moving forward

I'd definitely second that approach. As a workaround I've made sure that I've consolidated all nuget packages to the same version across the solution which has solved the problem, however this may not always be possible for all.

@JoeRobich
Copy link
Member

We could do a better job of Analyzer isolation if we could use the AssemblyDependencyResolver, but that type was introduced in 3.1. https://docs.microsoft.com/en-us/dotnet/api/system.runtime.loader.assemblydependencyresolver?view=netcore-3.1&viewFallbackFrom=netcore-2.1

That being said, we can certainly use a separate AssemblyLoadContext.

@JoeRobich JoeRobich added the Bug This issue describes behavior that is not working as expected label Aug 9, 2020
@jmarolf jmarolf self-assigned this Aug 19, 2020
@jmarolf jmarolf added this to the 5.0 milestone Feb 11, 2021
@jmarolf
Copy link
Contributor

jmarolf commented Feb 11, 2021

I believe this is fixed in version 5.0

@jmarolf jmarolf closed this as completed Feb 11, 2021
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Bug This issue describes behavior that is not working as expected
Projects
None yet
Development

No branches or pull requests

5 participants