提问人:ben yu 提问时间:3/17/2023 最后编辑:ben yu 更新时间:3/19/2023 访问量:422
如何替代 nuget 包的依赖项版本
How to override dependency version of a nuget package
问:
我有一个 .netstandard2.0 项目,假设它被称为 common,它使用 nuget.org 的 System.Configuration.ConfigurationManager 5.0.0 和 log4net 2.0.15。 此公共项目由项目 A(一个 .net5 项目)使用,也由项目 B(一个 .net Framework 4.6.1 项目)使用。 在 Common 项目中,我使用 System.Configuration.ConfigurationManager 和 log4net,如下所示:
<ItemGroup>
<PackageReference Include="log4net" Version="2.0.15" />
<PackageReference Include="System.Configuration.ConfigurationManager" Version="5.0.0" />
</ItemGroup>
现在,当log4net尝试初始化时.dll我遇到了System.Configuration.ConfigurationManager的程序集加载问题,因为它需要System.Configuration.ConfigurationManager的4.0.1.0而不是5.0.0。
错误消息如下所示:
System.IO.FileNotFoundException:无法加载文件或程序集“System.Configuration.ConfigurationManager,Version=4.0.1.0,Culture=neutral,PublicKeyToken=cc7b13ffcd2ddd51”。系统找不到指定的文件。
如何强制log4net.dll使用System.Configuration.ConfigurationManager 5.0.0.0? 我尝试添加一个log4net.dll.dll,如下所示,但不起作用。log4net 仍尝试加载旧版本的 System.Configuration.ConfigurationManager。除了从源代码重建log4net之外,还有人知道如何解决这个问题吗?
<configuration>
<runtime>
<assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
<dependentAssembly>
<assemblyIdentity name="System.Configuration.ConfigurationManager" publicKeyToken="cc7b13ffcd2ddd51" culture="neutral" />
<bindingRedirect oldVersion="0.0.0.0-5.0.0.0" newVersion="5.0.0.0" />
</dependentAssembly>
</assemblyBinding>
</runtime>
</configuration>
我检查了log4net.dll的元数据,它确实使用4.0.1.0版本System.Configuration.ConfigurationManager。我尝试使用上述语法重新绑定,但似乎被忽略了。
要重现此问题,您需要将 A 和 B 的输出文件夹设置为相同:
<OutputPath>$(SolutionDir)$(Configuraiton)$(Platform)</OutputPath>
<AppendRuntimeIdentifierToOutputPath>false</AppendRuntimeIdentifierToOutputPath>
<AppendTargetFrameworkToOutputPath>false</AppendTargetFrameworkToOutputPath>
另外,我发现如果我只重建A(或重建解决方案,三个项目A,B和Common在同一个解决方案中),然后通过右键单击->属性->详细信息检查输出文件夹中的log4net.dll属性,产品版本显示“2.0.15.0-NET Standard 2.0”。但是,如果我仅重建 B,它会变成“2.0.15.0-.NET 4.5”,在这种情况下,问题就消失了。仅当 log4net.dll 显示“2.0.15.0-NET Standard 2.0”时才会发生程序集加载问题。
答:
一切终于与您提供的最新信息汇集在一起。
根本问题是建立两个独立的'。NET的实现到同一个文件夹中。这是有原因的。AppendTargetFrameworkToOutputPath
dll 不能依赖于类库,反之亦然。这基本上就是这里发生的事情。构建的输出相互干扰,运行的内容基本上是您最近构建的输出。.NET
.NETFramework
当我按照你描述的方式设置我的项目时,我可以重新创建它。
项目A: , ProjectB: , Common: .net5.0
net461
netstandard2.0
Build -> Build 。 运行良好,但无法运行。 Build -> Build 。
运行良好,但不能。A
B
B
A
B
A
A
B
如果我将这个手卷程序集绑定重定向到 's appconfigB
<runtime>
<assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
<dependentAssembly>
<assemblyIdentity name="System.Configuration.ConfigurationManager" publicKeyToken="cc7b13ffcd2ddd51" culture="neutral" />
<bindingRedirect oldVersion="0.0.0.0-5.0.0.0" newVersion="5.0.0.0" />
</dependentAssembly>
</assemblyBinding>
</runtime>
Build -> Build . Both work, but this is very unreliable.B
A
If the assemblies are started via reflection, then you need to be extra careful because you need to make sure the CLR is loading the config files in the same way as it naturally would when starting the EXEs. This is what sets up all the binding redirects (app.config for , for )..NETFramework
deps.json
.NET
评论
interface
.NETFrameork
.NET
评论
cc7b13ffcd2ddd51