VS2017扩展引用System.Collections.Immutable出现版本冲突及方法找不到问题
解决VS2017扩展中Roslyn与System.Collections.Immutable的版本冲突问题
你遇到的是典型的程序集版本冲突场景——VS自身已经加载了与System.Core绑定的System.Collections.Immutable版本,而你的扩展引入了1.2.2.0版本,既导致类型重复定义,又引发Roslyn方法的版本依赖不匹配问题。以下是几个无需修改VS自身配置的可行解决方案:
1. 统一依赖版本,让NuGet自动管理依赖链
首先,建议你放弃手动引用System.Collections.Immutable,改为通过Roslyn相关NuGet包间接引入匹配版本:
- 移除项目中手动添加的
System.Collections.Immutable引用,确保所有Roslyn相关包(如Microsoft.CodeAnalysis、Microsoft.CodeAnalysis.CSharp)使用同一版本(VS2017对应的Roslyn版本一般为2.x系列,其依赖的System.Collections.Immutable恰好是1.2.2.0)。 - 检查项目的
packages.config或PackageReference配置,删除任何版本不一致的冲突依赖项,让NuGet自动维护依赖版本的一致性。
这种方式能从根源上避免多版本程序集共存的问题。
2. 在扩展初始化时强制指定程序集加载路径
如果统一版本后仍有冲突,可以通过AssemblyResolve事件拦截VS的程序集加载请求,强制返回你打包的正确版本:
在扩展的初始化类(继承自Package的类)中添加以下代码:
protected override void Initialize() { base.Initialize(); // 注册程序集解析事件 AppDomain.CurrentDomain.AssemblyResolve += CurrentDomain_AssemblyResolve; } private Assembly CurrentDomain_AssemblyResolve(object sender, ResolveEventArgs args) { var assemblyName = new AssemblyName(args.Name); // 仅处理System.Collections.Immutable的加载请求 if (assemblyName.Name.Equals("System.Collections.Immutable", StringComparison.OrdinalIgnoreCase)) { // 获取扩展安装目录下的目标程序集路径 var extensionAssemblyPath = GetType().Assembly.Location; var extensionDir = Path.GetDirectoryName(extensionAssemblyPath); var targetAssemblyPath = Path.Combine(extensionDir, "System.Collections.Immutable.dll"); return Assembly.LoadFrom(targetAssemblyPath); } return null; }
这段代码会在VS尝试加载System.Collections.Immutable时,强制返回你打包的1.2.2.0版本,绕过系统自带的版本。
3. 调整VSIX资产配置,提升扩展程序集优先级
检查你的source.extensions.vsixmanifest资产配置:
- 确保
System.Collections.Immutable、Microsoft.CodeAnalysis.dll、Microsoft.CodeAnalysis.CSharp.dll的Type设置为Microsoft.VisualStudio.Assembly,Source设置为File,Path指向项目输出目录中的正确版本文件。 - 将这些资产的
Visible属性设为true,提示VS优先加载扩展自带的程序集,而非系统全局版本。
4. 禁用自动绑定重定向,手动指定规则
如果项目启用了自动绑定重定向,可能会打乱版本匹配逻辑。可以在项目文件(.csproj)中禁用自动重定向,并手动添加明确的绑定规则:
<PropertyGroup> <AutoGenerateBindingRedirects>false</AutoGenerateBindingRedirects> <GenerateBindingRedirectsOutputType>false</GenerateBindingRedirectsOutputType> </PropertyGroup>
然后在扩展的app.config中添加绑定重定向规则:
<configuration> <runtime> <assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1"> <dependentAssembly> <assemblyIdentity name="System.Collections.Immutable" publicKeyToken="b03f5f7f11d50a3a" culture="neutral" /> <bindingRedirect oldVersion="0.0.0.0-1.2.2.0" newVersion="1.2.2.0" /> </dependentAssembly> </assemblyBinding> </runtime> </configuration>
记得将app.config的“复制到输出目录”设置为“如果较新则复制”,确保VS加载扩展时能读取到这个配置。
内容的提问来源于stack exchange,提问作者Matt Burland
相关产品推荐
相关产品推荐

