我遇到一个问题,当我在 Visual Studio 中运行应用程序时,通过 IOptionsMonitor 从配置加载到构造函数中的选项会被填充,但如果我从命令提示符运行构建的 .exe 则不会填充。
我一定错过了一些与配置有关的基本事情,但我就是无法解决它。
任何帮助将不胜感激,因为我不知所措,并且已经为此苦苦挣扎了一段时间......
我已将代码放在底部以显示我所看到的内容。
当我在 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”文件,如下所示(设置为“如果较新则复制”):
{
"SampleOptions": {
"IntegerProperty": 1
}
}
更新:托管环境
我添加了下面的代码,并确认问题与评论中建议的当前目录有关:
var hostingEnvironment = host.Services.GetRequiredService<IHostEnvironment>();
Console.WriteLine($"hostingEnvironment.EnvironmentName: {hostingEnvironment.EnvironmentName}");
Console.WriteLine($"hostingEnvironment.ContentRootPath: {hostingEnvironment.ContentRootPath}");
命令窗口输出:
更新:
修复方法是设置 ContentRoot:
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();
}
案件已结。
参考J M的解决方案:
需要添加
.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();
}