.NET Framework项目调用类库时Serilog无日志输出问题问询
问题根因
这个问题是.NET Framework程序集加载机制的特性导致的,和Serilog本身的设计无关。Serilog的静态Log类确实只需要配置一次即可全局生效,不需要跨程序集传递实例,出现该问题的核心原因是两个项目运行时加载的Serilog程序集不是同一个实例,导致两边访问的Log.Logger静态属性属于不同的类,自然类库中访问到的还是默认的无输出静默日志器。
常见触发场景有两种:
- 两个项目安装的Serilog NuGet包版本表面一致,但实际依赖链中存在版本差异,.NET Framework默认严格匹配程序集版本,没有绑定重定向的情况下会加载多份Serilog程序集
- 类库项目的Serilog引用配置错误,开启了「特定版本」限制,导致运行时加载了和控制台项目不一致的Serilog副本
修复步骤
- 统一Serilog版本
打开解决方案的NuGet包管理器,在「合并(Consolidate)」标签下将所有项目的Serilog相关包统一为相同版本,避免版本差异。 - 添加正确的绑定重定向
在控制台项目的app.config文件中添加Serilog的绑定重定向配置,强制所有项目都加载同一版本的Serilog程序集:
<configuration> <!-- 原有配置 --> <runtime> <assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1"> <dependentAssembly> <assemblyIdentity name="Serilog" publicKeyToken="24c2f752a8e58a10" culture="neutral" /> <bindingRedirect oldVersion="0.0.0.0-2.10.0.0" newVersion="2.10.0.0" /> </dependentAssembly> <!-- 如果有其他Serilog相关包的版本差异,也可以在这里添加对应的重定向规则 --> </assemblyBinding> </runtime> </configuration>
你也可以右键点击控制台项目,选择「添加绑定重定向」让Visual Studio自动生成所有缺失的重定向规则。
3. 校验引用配置
分别打开两个项目的引用列表,找到Serilog引用,右键打开属性面板,确认两个项目的Serilog引用都设置为:
- 特定版本:False
- 复制本地:True
- 调试验证(可选)
如果需要确认问题根因,可以分别在控制台项目完成Log.Logger赋值后、类库方法调用Log前加入如下代码,对比输出的哈希值和程序集全名是否一致:
// 输出日志器实例哈希,不同则说明是不同实例 Console.WriteLine(Log.Logger.GetHashCode()); // 输出Serilog程序集全名,不同则说明加载了多份Serilog Console.WriteLine(typeof(Log).Assembly.FullName);
如果输出不一致即可实锤是程序集加载差异导致的问题,完成上述修复步骤后两个值会变为一致,类库中的日志调用也会正常输出。
内容的提问来源于stack exchange,提问作者Hydrargyrum
相关产品推荐
相关产品推荐

