-
Notifications
You must be signed in to change notification settings - Fork 508
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
Newtonsoft.Json is installed as an analyzer #1624
Comments
It's not intentional, but as far as I can tell it's also not avoidable. |
What requires it there? I experimented by commenting out that Analyzer in the
and StyleCop seems to be running as expected, even after restarting Visual Studio 2015. |
NuGet automatically adds that line because the assembly is located in the StyleCop.Analyzers NuGet package. We don't add it on purpose, but we need to distribute Newtonsoft.Json with the analyzers so the stylecop.json settings work properly. |
It's not NuGet itself, but StyleCop.Analyzer's install Powershell script: https://github.com/DotNetAnalyzers/StyleCopAnalyzers/blob/master/StyleCop.Analyzers/StyleCop.Analyzers/tools/install.ps1#L41 But yeah, I do now see the problem you mentioned. |
I completely forgot about that custom install script. 😫 |
It would be better if you were to use the same version of NewtonSoft JSon that ships with Visual Studio... Plus, it now forces all analyzers that depend on this assembly to use at least your version. Wouldn't statically registering an AppDomain.AssemblyResolve event allow you to fetch the assembly either from the same directory the main assembly is stored, or a tools assembly folder?! |
I haven't noticed any negative interaction between our assembly reference and Visual Studio. What problem(s) would you anticipate solving by changing the version we use?
Everything involved uses strong names. What would keep another analyzer assembly from including its own version of Newtonsoft.Json (e.g. 6.x) and referencing that? I would expect both references to load side-by-side.
It's possible, but I'd want a better understanding of the problems with the current approach as well as input from the analyzers team (e.g. @mavasani, @tmeschter) before going down this path. |
I tried adding a second reference (from my own analyzer pack) to version 6.05, but only one version sticks. So the analyzer that sets the reference last will probably win, causing funny issues. I don't see a way to set binding redirects for Analyzers, so looking for a fellow-analyzer to load dependent assemblies feels like a bad design decision. While strong names would work just fine, every AppDomain can only load one version of each strong named assembly at a time, I'm not entirely sure whether analyzers are running in their own AppDomain, which would allow you to load your own version, otherwise the first assembly to load its dependencies wins. This is already causing massive issues with VSIX extensions loading different versions of the same dependent assembly in different orders. I can't say for sure whether one analyzer with a dependency could cause these issues, but multiple will, as it looks like. The issues usually surface as component model cache corruptions: http://stackoverflow.com/questions/20301697/visual-studio-2013-is-unable-to-open-the-test-window Right now, and for quite some time now, Visual Studio ships with version 6.05 of Newtonsoft.Json and stores in a common location which can easily be resolved. Alternate options would be to link these dependencies statically or to compile them as internal classes to the analyzer from source. or to load them from a well known location off of the analyzers own assembly location. I see no need to add your dependencies to the project causing your implementation details to seep into the projects that use the analyzer. |
@sharwell @jessehouwing If an analyzer assembly A.dll depends on another assembly B.dll, then both must be listed as analyzers. This is to ensure that the host application knows where to find dependencies and can load the correct one. Exceptions: You do not need to and should not include the core system assemblies (e.g., mscorlib.dll, System.dll) as you generally have no control over those, or the core Roslyn assemblies (e.g., Microsoft.CodeAnalysis.dll) or their dependencies (e.g., System.Collections.Immutable.dll) as those will be provided by the host application and you can assume they are already loaded. The point of this requirement is to ensure consistent analyzer behavior, especially from one build to the next. Consider what would happen if your analyzer ended up with one copy of Newtonsoft.Json.dll in VS, and a different copy when building in the command line. You could conceivably get different results from your analyzer. You could run into even worse problems when compilation is handled by vbcsserver.exe. Since that is a long-running process that will handle multiple builds, exactly which dependencies are loaded could depend on the order in which the builds occur. Which means that the set of diagnostics reported could also be dependent on the build order, or even whether or not the build succeeds. We avoid these issues by requiring that dependencies be specified. That way we can try to load exactly the assembly that is expected, and if we can't, we can check to see if that is OK or might pose a problem. I don't have time for a fuller explanation (I'll get back to that later), so here's some brief guidance:
|
I'm having trouble reproducing this behavior. I added Newtonsoft.Json 6.0.4 as an additional analyzer reference, and everything seems to still be working. This worked whether I placed it as the first analyzer or the last analyzer in the list. It even showed up twice in the list of analyzers: ❓ Is the other analyzer pack open source and available so I can test with it as well?
Our deployment is relying on side-by-side loading of assemblies with different versions. Binding redirects override this behavior and cause different assemblies to be treated as equivalent. In other words, I would expect things to work correctly now, but binding redirects would actually break them.
This is not (normally) correct. When using strong names, two assemblies which differ only by their assembly version are treated as two completely different assemblies and can be loaded side-by-side in the same AppDomain. There may be ways to override this behavior, but if things weren't already confusing enough with the default behavior for strong-named assemblies...
I believe the problems you refer to here are actually related to the way MEF locates parts. There is a good chance that one or more MEF-exported components failed to follow one or more items in Assembly Versioning in Extensible Applications (search for 'MEF' in that page). |
@jessehouwing Is the other analyzer you're working with SonarSource/sonarlint-vs? If so, it appears from the project file (this is the only project I saw that references Newtonsoft.Json) that the analyzer assembly for that project does not have a strong name. You will need to add a strong name to your assembly before side-by-side assembly loading will work. |
@tmeschter I'm going to take a guess that the loading logic behaves as follows. Suppose AnalyzerA does have a strong name and references X version 2. Also suppose AnalyzerB does not have a strong name and references X version 1. If both AnalyzerA and AnalyzerB are added to a project, then one of the following sequences will occur:
Alternately:
|
Alright, I set up a complicated case to experiment with this. In sharwell/StyleCopAnalyzers@ca42b3e, I made our analyzer assembly depend on both Newtonsoft.Json 6.0.0.0 and Newtonsoft.Json 7.0.0.0. If either assembly fails to load with that specific version, half the analyzers which use stylecop.json will fail. When I installed the updated package (sharwell/StyleCopAnalyzers@da335ec), you can see that the installation script failed to add both references to Newtonsoft.Json, even though they were both present in the .nupkg file. As expected, a large number of warnings were reported in the IDE regarding failure to load analyzers. However, when I manually added the second reference (sharwell/StyleCopAnalyzers@557cac8), everything worked. It looks like this is a bug in either the installation script or in the project system. |
@jessehouwing I filed dotnet/roslyn#6322 regarding the failure to include both analyzer references when packages are installed through NuGet. For now I'm going to close this as external for the following reasons:
|
When installing StyleCop.Analyzers,
Newtonsoft.Json
is installed as an Analyzer.Is this intentional? Is it possible to ship an Analyzer dependency without installing the dependency itself as an analyzer?
The text was updated successfully, but these errors were encountered: