.NET6中如何解决项目引用与NuGet包引用冲突问题?
问题核心
Project A(已升级至.NET6)通过ProjectReference引用本地Project B,同时引用的Package C依赖特定版本的NuGet包Package B。构建时仅输出本地Project B的DLL,但运行时Package C调用Project B时提示找不到对应版本的DLL——原.NET Framework的AutoGenerateBindingRedirects在.NET6中不再生效,且需保留ProjectReference。
可行解决方案
1. 手动添加程序集绑定重定向
.NET6仍支持程序集绑定重定向,仅需手动配置,分两种场景:
桌面/控制台应用:在Project A的
app.config中添加绑定规则:<configuration> <runtime> <assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1"> <dependentAssembly> <assemblyIdentity name="ProjectB" publicKeyToken="替换为ProjectB的公钥令牌" culture="neutral" /> <!-- oldVersion覆盖Package C依赖的版本范围 --> <bindingRedirect oldVersion="0.0.0.0-x.y.z.w" newVersion="本地ProjectB构建的版本号" /> </dependentAssembly> </assemblyBinding> </runtime> </configuration>公钥令牌可通过命令
sn -T ProjectB.dll获取,版本号查看构建后DLL的属性详情。ASP.NET Core应用:修改
runtimeconfig.json(或在csproj中配置自动生成):{ "runtimeOptions": { "assemblyBinding": { "dependentAssembly": [ { "assemblyIdentity": { "name": "ProjectB", "publicKeyToken": "替换为对应公钥令牌", "culture": "neutral" }, "bindingRedirect": { "oldVersion": "0.0.0.0-x.y.z.w", "newVersion": "本地构建版本号" } } ] } } }
2. 排除Package C对Package B的依赖
在Project A的csproj中,修改对Package C的引用,排除其传递依赖的Package B,强制使用本地Project B:
<PackageReference Include="PackageC" Version="你的PackageC版本"> <!-- 排除Package B的传递依赖 --> <ExcludeAssets>PackageB</ExcludeAssets> <!-- 抑制版本冲突警告 --> <NoWarn>NU1605</NoWarn> </PackageReference>
3. 同步Project B版本与Package C依赖版本
直接将本地Project B的版本号修改为Package C依赖的版本,从根源避免版本不匹配:
在Project B的csproj中设置版本属性:
<PropertyGroup> <!-- 替换为Package C依赖的Package B版本号 --> <Version>x.y.z.w</Version> </PropertyGroup>
构建后Project B的DLL版本与Package C预期一致,运行时不会出现版本查找错误。
4. 手动干预程序集加载(兜底方案)
如果以上方法无效,可在Project A启动时通过AssemblyLoadContext强制加载本地Project B DLL:
using System.Reflection; using System.Runtime.Loader; using System.IO; // 加载本地ProjectB DLL var projectBDllPath = Path.Combine(AppContext.BaseDirectory, "ProjectB.dll"); var localAssembly = AssemblyLoadContext.Default.LoadFromAssemblyPath(projectBDllPath); // 拦截程序集加载请求,匹配ProjectB时返回本地版本 AssemblyLoadContext.Default.Resolving += (context, assemblyName) => { if (assemblyName.Name.Equals("ProjectB", StringComparison.OrdinalIgnoreCase)) { return localAssembly; } return null; };
内容的提问来源于stack exchange,提问作者Joshua Sutherland

