@ljw1004 commented on Tue Jun 28 2016
Version Used: VS2015 Update2, and Update3
Steps to Reproduce:
- File > New > C# > Extensibility > Code Refactoring (VSIX)
- References > Manage NuGet packages > Installed > System.Collections.Immutable > upgrade to v1.2.0
- Add this code:
// Add this inside the start of ComputeRefactoringsAsync:
try { test(false); }
catch (System.Exception ex) {
System.Diagnostics.Debug.WriteLine(ex.Message);
}
// This is the method "test":
void test(bool b)
{
if (!b) return;
Solution s = null;
s.GetDocumentIdsWithFilePath("");
}
Expected Behavior:
It should either work at runtime, or give a build-time error.
Actual Behavior:
It builds okay. At runtime it never enters method test
. Instead it hits the catch block with exception Could not load System.Collections.Immutable v1.2.0
Discussion:
I believe that the Visual Studio process already has a particular version of System.Collections.Immutable
loaded into its address space. This seems to be version 1.1.37 in both Update2 and Update3.
Now my VSIX comes along and is loaded into the same address space. It had been compiled against v1.2.0 of System.Collections.Immutable, but only v1.1.37 is loaded.
When I attempt to invoke my method test()
which contains calls to a Roslyn API which returns an immutable array (e.g. Solution.GetDocumentIdsWithFilePath
) then upon first entry to this method, the JIT tries to load all types it needs to compile this method. But it's unable to load System.Collections.Immutable. It therefore fails to JIT my method test()
.
This is all really subtle and hard to discover, and easy to run into...
- The File>New>Refactoring template happens to avoid it because File>New spits out a NuGet reference to System.Collections.Immutable v1.1.36. But NuGet users are likely to upgrade their packages just to get rid of the irritating NuGet "updates available" flag.
- It's not even clear to the user why System.Collections.Immutable reference is even there. A tidy-minded user is likely to switch over to project.json, and then only use the minimum set of NuGet references (just Microsoft.CodeAnalysis.CSharp.Workspaces on its own will suffice).
- Actually, when I did File>New>Refactoring, uninstalled all the nugets, created a new project.json, and installed solely the nuget Microsoft.CodeAnalysis.CSharp.Workspaces v1.2.2, then it brought in a dependency on System.Collections.Immutable 1.2.0. And I had expected this to fail like the above. But it succeeded! I don't know why!
- When I tried to do a larger VSIX project with a few more Roslyn references - https://blogs.msdn.microsoft.com/lucian/2016/06/27/visual-studio-text-adornment-vsix-using-roslyn/ - then it did run into the System.Collections.Immutable 1.2.0 problem. I'm not sure why.
What I think should happen:
This is confusing...
- Why does System.Collections.Immutable get updated so often?
- Can there be a binding redirect so that VS is happy to pull in a newer version of it?
- Should one of the nuget packages e.g.
Microsoft.VisualStudio.LanguageService
have a hard-coded dependency on the exact right version of System.Collections.Immutable so that NuGet doesn't silently pick a newer one?
I honestly don't know. But the status quo feels like dangerous -- it's a narrow golden path, and impossible to know that certain reasonable actions will lead you astray, and hard to debug what's gone wrong.
@ljw1004 commented on Tue Jun 28 2016
I know! Let's have a few different NuGet packages:
Microsoft.VisualStudio compatibility check for VS2015 Update 2 or higher
Microsoft.VisualStudio compatibility check for VS2015 Update 3 or higher
...
And the templates will add a reference to the appropriate one of these. These NuGet packages don't contain any libraries. All they do is have "exact version dependencies" on other NuGets, to make sure you don't pick a too-recent version of anything.
I figure the names of these packages will be self-documenting enough.
@jmarolf commented on Fri Dec 15 2017
Issue moved to dotnet/roslyn-sdk #56 via ZenHub
@jmarolf commented on Fri Dec 15 2017
Issue moved to dotnet/roslyn-sdk #57 via ZenHub
@jmarolf commented on Fri Dec 15 2017
Issue moved to dotnet/roslyn-sdk #58 via ZenHub