如何在Main方法中为NLog.config传入PostgreSQL连接串与日志目录?
在Main方法中传递配置给NLog.Config的正确姿势
看起来你遇到的问题核心是NLog在Main方法中初始化时,还没拿到你在Startup里设置的变量——因为Main是程序的入口点,执行顺序早于Startup,这时候你在Startup里修改的NLog配置变量还没生效,自然会导致Main里的日志输出异常(比如数据库连接失败、日志路径错误之类的)。
下面是具体的解决方案,分两种场景(传统Main方法和.NET 6+顶级语句)来演示:
一、传统.NET Core项目(带Main方法的Program.cs)
你需要在Main方法里先加载应用配置,再初始化NLog并设置变量,确保NLog在创建Logger之前就拿到正确的配置值:
using Microsoft.Extensions.Configuration; using NLog; using System.IO; namespace YourProjectNamespace { public class Program { public static void Main(string[] args) { // 第一步:加载应用配置(从appsettings.json) var configBuilder = new ConfigurationBuilder() .SetBasePath(Directory.GetCurrentDirectory()) .AddJsonFile("appsettings.json", optional: false, reloadOnChange: true); IConfigurationRoot appConfig = configBuilder.Build(); // 第二步:加载NLog配置并设置变量 var nlogConfig = LogManager.LoadConfiguration("nlog.config"); // 设置PostgreSQL连接字符串变量 nlogConfig.Variables["connectionString"] = appConfig.GetConnectionString("databaseConnectionString"); // 设置日志目录变量 nlogConfig.Variables["configDir"] = appConfig.GetValue<string>("Logging:LogFilePath"); // 让NLog使用更新后的配置 LogManager.Configuration = nlogConfig; // 现在创建Logger并记录日志,变量已经生效了 var logger = LogManager.GetCurrentClassLogger(); logger.Info("Main方法中的日志:连接字符串和日志路径已正确配置!"); // 第三步:创建并启动WebHost CreateHostBuilder(args).Build().Run(); } public static IHostBuilder CreateHostBuilder(string[] args) => Host.CreateDefaultBuilder(args) .ConfigureWebHostDefaults(webBuilder => { webBuilder.UseStartup<Startup>(); }) .UseNLog(); // 集成NLog到Host } }
二、.NET 6+ 顶级语句版本的Program.cs
如果你的项目用了.NET 6及以上的顶级语句,代码会更简洁:
using Microsoft.Extensions.Configuration; using NLog; var builder = WebApplication.CreateBuilder(args); // 直接从builder.Configuration读取配置值 var connectionString = builder.Configuration.GetConnectionString("databaseConnectionString"); var logDir = builder.Configuration.GetValue<string>("Logging:LogFilePath"); // 加载并更新NLog配置 var nlogConfig = LogManager.LoadConfiguration("nlog.config"); nlogConfig.Variables["connectionString"] = connectionString; nlogConfig.Variables["configDir"] = logDir; LogManager.Configuration = nlogConfig; // 清除默认日志提供器,添加NLog builder.Logging.ClearProviders(); builder.Logging.AddNLog(); var app = builder.Build(); // 这里可以添加你的中间件配置... app.Run();
关键注意事项
确保NLog.Config中已定义对应变量
你的nlog.config里需要先声明这些变量,这样即使配置加载失败也有默认值兜底,比如:<nlog xmlns="http://www.nlog-project.org/schemas/NLog.xsd" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"> <!-- 提前声明变量,设置默认值 --> <variable name="connectionString" value="default_connection_string"/> <variable name="configDir" value="./logs"/> <!-- 后续的targets和rules可以直接使用这些变量 --> <targets> <target xsi:type="Database" name="db" connectionString="${var:connectionString}" ... /> <target xsi:type="File" name="file" fileName="${var:configDir}/log-${shortdate}.txt" ... /> </targets> </nlog>避免重复配置
既然已经在Main/顶级语句里设置了NLog变量,就不需要再在Startup.cs里重复执行LogManager.Configuration.Variables[...]的代码了,否则可能导致配置冲突。使用NLog官方集成包
确保你已经安装了NLog.Web.AspNetCore(ASP.NET Core项目)或者NLog.Extensions.Logging(通用.NET项目),这样NLog才能和.NET的日志系统无缝集成。
内容的提问来源于stack exchange,提问作者Salih H.
相关产品推荐
相关产品推荐

