如何覆盖NuGet包依赖版本?解决log4net程序集加载异常
我有一个名为Common的.NET Standard 2.0项目,通过NuGet引入了System.Configuration.ConfigurationManager 5.0.0和log4net 2.0.15,该项目同时被.NET 5项目A和.NET Framework 4.6.1项目B引用。
Common项目的包引用配置:
<ItemGroup> <PackageReference Include="log4net" Version="2.0.15" /> <PackageReference Include="System.Configuration.ConfigurationManager" Version="5.0.0" /> </ItemGroup>
log4net初始化时抛出程序集加载异常,错误信息:
System.IO.FileNotFoundException: Could not load file or assembly 'System.Configuration.ConfigurationManager, Version=4.0.1.0, Culture=neutral, PublicKeyToken=cc7b13ffcd2ddd51'. The system cannot find the file specified.
经检查log4net元数据,确认它依赖4.0.1.0版本的System.Configuration.ConfigurationManager,但我尝试添加的log4net.dll.config绑定重定向未生效,配置如下:
<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>
复现条件
将项目A和B的输出目录设置为同一目录,配置如下:
<OutputPath>$(SolutionDir)$(Configuraiton)$(Platform)</OutputPath> <AppendRuntimeIdentifierToOutputPath>false</AppendRuntimeIdentifierToOutputPath> <AppendTargetFrameworkToOutputPath>false</AppendTargetFrameworkToOutputPath>
现象差异
- 仅重建A或整个解决方案时,输出目录中log4net.dll的产品版本为
2.0.15.0-NET Standard 2.0,异常触发; - 仅重建B时,产品版本变为
2.0.15.0-.NET 4.5,异常消失。
现需解决:除从源码重建log4net外,如何强制log4net.dll使用System.Configuration.ConfigurationManager 5.0.0.0版本?
1. 将绑定重定向移至主项目配置文件
CLR不会自动读取log4net.dll.config,绑定重定向必须配置在主应用程序的配置文件中:
- 对于.NET 5项目A:修改项目根目录的
app.config(或生成后的A.dll.config),添加绑定重定向节点; - 对于.NET Framework项目B:直接修改
App.config,插入对应配置。
示例配置(添加到主项目配置文件的<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>
2. 强制Common项目引用log4net的.NET Framework版本
log4net是多目标包,当输出目录共享时,.NET Standard版本会被优先复制。可在Common项目的.csproj中强制指定引用兼容.NET Framework的包版本:
<ItemGroup> <PackageReference Include="log4net" Version="2.0.15"> <TargetFrameworks>net461</TargetFrameworks> </PackageReference> <PackageReference Include="System.Configuration.ConfigurationManager" Version="5.0.0" /> </ItemGroup>
或添加AssetTargetFallback确保优先选择.NET Framework兼容资产:
<PropertyGroup> <AssetTargetFallback>$(AssetTargetFallback);net461</AssetTargetFallback> </PropertyGroup>
3. 取消输出目录共享
移除A和B的输出目录统一配置,保留各自的目标框架/运行时标识目录,避免不同版本的log4net互相覆盖:
- 删除
AppendRuntimeIdentifierToOutputPath和AppendTargetFrameworkToOutputPath的false设置,恢复默认行为; - 或为A、B设置差异化输出路径,例如
$(SolutionDir)$(Configuration)$(Platform)\$(TargetFramework)。
内容的提问来源于stack exchange,提问作者ben yu

