ryc*_*moj 14 c# configuration json .net-core
我试图GetSection从注入的配置调用Startup.cs.值是null,而indexer具体部分值返回non-null值.在我看来这个GetSection方法背后的错误或我错了吗?
appsettings.json:
{"MyConfig":{"ConfigA":"valueA","ConfigB":"valueB"}}
Program.cs中:
public static void Main(string[] args)
{
var host = BuildWebHost(args);
host.Run();
}
public static IWebHost BuildWebHost(string[] args) =>
WebHost.CreateDefaultBuilder(args)
.UseStartup<Startup>()
.Build();
Run Code Online (Sandbox Code Playgroud)
Startup.cs:
public class Startup
{
public Startup(IConfiguration configuration)
{
Configuration = configuration;
}
public IConfiguration Configuration { get; }
// This method gets called by the runtime. Use this method to add services to the container.
public void ConfigureServices(IServiceCollection services)
{
services.AddMvc();
}
// This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
public void Configure(IApplicationBuilder app, IHostingEnvironment env)
{
var mySection = this.Configuration.GetSection("MyConfig");
var myVal = this.Configuration["MyConfig:ConfigA"];
Run Code Online (Sandbox Code Playgroud)
Mat*_*kan 12
我第一次检查,看看是否有之间的任何变化1.1.1和2.X的JsonConfigurationProvider.cs,最终从您的JSON文件构建检索值的内部代码.这个或任何其他最终被您调用的代码没有变化this.Configuration.GetSection("MyConfig");.
检索值的方法是,Configuration将按照代码中定义的相反顺序MyConfig在每个配置提供程序中查找您的密钥,直到找到值.在您的示例中,提供者(json,envionment变量,命令行参数)在Webhost.CreateDefaultBuilder() (见此处)中提供.
查看JsonConfigurationFileParser.cs的代码,它构建了一个Dictionary<string, string>for键和值,但仅用于原始值.也就是说,没有键被存储用于MyConfig(在这一级它是一个对象),但将有一个键MyConfig:ConfigA和阵列值将看起来像MyConfig:ConfigA:0,MyConfig:ConfigA:1等等.
最后,你会发现,Configuration.GetSection("MyConfig") 总是返回你一个新建成的 ConfigurationSection是永远不能为null,而在最糟糕的将有Value 属性的null.
那么当你将鼠标悬停在ConfigurationSection智能感知器上并查看Value属性时会发生的情况是,每个配置提供程序都已被搜索,并且没有一个被发现有一个"MyConfig"键,其原始值转换为字符串返回.
你至少需要打电话:
services.Configure<MyConfigOptions>(configuration.GetSection("MyConfig"));
services.AddSingleton(cfg => cfg.GetService<IOptions<MyConfigOptions>>().Value);
Run Code Online (Sandbox Code Playgroud)
将它作为C#对象注入整个应用程序.否则,使用冒号["MyConfig:ConfigA"]分隔符语法或使用,调用单个值var mySection = this.Configuration.GetSection("MyConfig")["ConfigA"];,这是多余的,但说明它仅用于检索基元.
要绑定到C#对象并注入它们,我创建了以下扩展方法:
public static class IServiceCollectionExtensions
{
public static IServiceCollection AddConfigOptions<TOptions>(this IServiceCollection services,
IConfiguration configuration, string section) where TOptions : class, new()
{
services.Configure<TOptions>(configuration.GetSection(section));
services.AddSingleton(cfg => cfg.GetService<IOptions<TOptions>>().Value);
return services;
}
}
Run Code Online (Sandbox Code Playgroud)
可以像这样调用:
public class Startup
{
public Startup(IConfiguration configuration) => Configuration = configuration;
public IConfiguration Configuration { get; }
public void ConfigureServices(IServiceCollection services)
{
services.AddConfigOptions<EmailOptions>(Configuration, "Email")
Run Code Online (Sandbox Code Playgroud)
并注入如下:
public class EmailSender : IEmailSender
{
private EmailOptions _emailOptions;
public EmailSender(EmailOptions options) => _emailOptions = options;
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
13376 次 |
| 最近记录: |