You need to enable JavaScript to run this app. .NET Framework下Serilog NuGet包收敛至日志类库的实现及加载异常排查
优惠活动
大模型
产品
解决方案
定价
更多

.NET Framework下Serilog NuGet包收敛至日志类库的实现及加载异常排查

异常产生的核心原因
  • 你当前使用的.NET Framework非SDK风格项目默认采用 packages.config 模式管理NuGet包,这种模式下类库项目安装的依赖不会自动传递到主程序的输出目录:主程序编译时只会把类库本身的编译产物Library.dll复制到自身运行目录,类库依赖的所有Serilog Sink、Enricher对应的DLL不会被自动同步,主程序运行时自然无法找到这些文件。
  • Serilog 的 ReadFrom.AppSettings() 实现,是通过配置文件中写入的程序集名称字符串,在主程序的运行时加载上下文里动态扫描、加载对应程序集的,不会从类库的编译路径查找DLL。只要主程序运行目录里缺少Serilog.Sinks.Console这类配置中点名的程序集,就会直接抛出FileNotFoundException。这也是为什么只有把所有Serilog相关包安装到主程序时项目才能正常运行——本质是把缺失的DLL直接放到了主程序的输出目录。
  • 当前类库的初始化逻辑存在设计缺陷:虽然手动写了File Sink的配置,但App.config中所有Console、Seq、Enricher的配置完全依赖动态加载,没有在代码层面和对应程序集做编译期绑定,进一步放大了程序集加载失败的概率。
实现Serilog依赖仅存放在类库的调整方案
  • 第一步,切换NuGet包管理格式
    将项目默认的NuGet管理格式从 packages.config 切换为 PackageReference:在Visual Studio的NuGet通用设置中,把默认包管理格式修改为PackageReference,重新还原所有项目的NuGet包即可。这种模式下NuGet会自动计算整个引用链路的全部依赖,把类库项目用到的所有Serilog相关DLL自动复制到主程序的输出目录,不需要主程序重复安装相同的包。
    切换完成后,可在类库项目的引用列表中检查所有Serilog相关依赖的属性,确保复制本地选项设置为True,避免DLL漏复制到输出目录。
  • 第二步,调整Serilog初始化逻辑,消除动态加载依赖
    把App.config中所有需要动态扫描程序集的配置,挪到类库的初始化代码中做显式绑定,完全去掉对App.config动态加载的依赖——动态加载本身受程序集探测路径限制,编译期的显式引用绑定不会出现运行时找不到程序集的问题。
    调整后的LoggerInstaller.cs核心代码参考:
    using Serilog;
    
    namespace Library
    {
        static public class LoggerInstaller
        {
            static public Serilog.Core.Logger Install()
            {
                string logFileName = "MyLog.log";
    
                var config = new LoggerConfiguration()
                    // 对应原App.config的最小日志级别配置
                    .MinimumLevel.Verbose()
                    // 显式注册Console Sink,替代App.config的动态加载逻辑
                    .WriteTo.Console(outputTemplate: "{Timestamp:HH:mm:ss} [{Level}] [{SourceContext}] {Message}{NewLine}{Exception}")
                    // 显式注册Seq Sink
                    .WriteTo.Seq("http://localhost:5341")
                    // 保留原有File Sink参数配置
                    .WriteTo.File(logFileName, rollingInterval: RollingInterval.Day, rollOnFileSizeLimit: true, fileSizeLimitBytes: 50000)
                    // 显式注册全部Enricher,替代App.config的动态加载逻辑
                    .Enrich.WithThreadId()
                    .Enrich.FromLogContext()
                    .Enrich.WithMachineName()
                    .Enrich.WithProcessId()
                    .Enrich.WithMemoryUsage()
                    .Enrich.WithAssemblyName()
                    .Enrich.WithAssemblyVersion()
                    .Enrich.WithProperty("Application", "SerilogTest")
                    .CreateLogger();
    
                Log.Logger = config;
                return config;
            }
        }
    }
    
  • 第三步,清理主程序App.config的冗余配置
    把原App.config中所有serilog:using:*、serilog:write-to:*、serilog:enrich:*的节点全部删除,避免Serilog再次触发动态程序集加载逻辑,从根源上消除文件找不到的异常。

内容的提问来源于stack exchange,提问作者Q-bertsuit

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.11.08 22:06:05