IOptionsMonitor在VS中正常加载配置,exe运行时失效问题
IOptionsMonitor配置在VS运行正常但直接运行exe无法加载的问题解决
问题现象
使用IOptionsMonitor将配置注入到构造函数的选项时,在Visual Studio中运行应用,配置能正常填充;但直接运行生成的.exe文件时,配置无法加载,选项值为空。
复现代码
程序代码
using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Hosting; using Microsoft.Extensions.Options; namespace ConsoleApp1; public static class Program { #region Public interface public static void Main() { try { var host = BuildHost(); var test = host.Services.GetRequiredService<Consumer>(); test.DoSomething(); } finally { Console.ReadLine(); } } #endregion #region Private interface private static IHost BuildHost() { var host = Host.CreateDefaultBuilder() .ConfigureServices((context, services) => { services.Configure<SampleOptions>(context.Configuration.GetSection("SampleOptions")); services.AddSingleton<Consumer, Consumer>(); }) .Build(); return host; } #endregion } public class SampleOptions { public int? IntegerProperty { get; set; } } public class Consumer { public Consumer(IOptionsMonitor<SampleOptions> optionsMonitor) { OptionsMonitor = optionsMonitor; } private IOptionsMonitor<SampleOptions> OptionsMonitor { get; } public void DoSomething() { var options = OptionsMonitor.CurrentValue; if (!options.IntegerProperty.HasValue) Console.WriteLine("options.IntegerProperty is NULL"); else Console.WriteLine("options.IntegerProperty is not NULL"); } }
配置文件(appsettings.json)
已设置为Copy If Newer,内容如下:
{ "SampleOptions": { "IntegerProperty": 1 } }
排查过程
添加代码输出IHostEnvironment信息,确认问题与内容根目录有关:
var hostingEnvironment = host.Services.GetRequiredService<IHostEnvironment>(); Console.WriteLine($"hostingEnvironment.EnvironmentName: {hostingEnvironment.EnvironmentName}"); Console.WriteLine($"hostingEnvironment.ContentRootPath: {hostingEnvironment.ContentRootPath}");
运行exe后发现,输出的内容根目录不符合预期,即程序未在正确的目录下读取配置文件。
解决方案
修改BuildHost方法,通过.UseContentRoot(AppContext.BaseDirectory)指定内容根目录为程序集所在目录,确保程序能找到配置文件:
private static IHost BuildHost() { return Host.CreateDefaultBuilder() .UseContentRoot(AppContext.BaseDirectory) .ConfigureServices((context, services) => { services.Configure<SampleOptions>(context.Configuration.GetSection("SampleOptions")); services.AddSingleton<Consumer, Consumer>(); }) .Build(); }
内容的提问来源于stack exchange,提问作者J M
相关产品推荐
相关产品推荐

