问题描述
我遇到了一个奇怪的问题,我似乎无法使用Configuration.Get<T>()
从我的appsettings.Development.json文件绑定appsettings值。
我已经以完全相同的方式在不同项目上完成了无数次,但显然“这次没有”。
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)
{
var myConfig = Configuration.Get<MySettingType>();
}
}
通常,这很完美。 我对Program.cs进行的任何编辑都没有进行任何整理,因为它可以更改有关加载appsettings文件的默认行为。 MySettingType与appsettings文件中的键的名称相同,匹配类使用的属性都是公共的。 该配置也位于json文件的根目录。
发生的事情是该代码只会导致在myConfig
对象中填充空值。
现在,我使用以下代码而不是Configuration.Get<T>()
解决了该问题:
var myConfig = new MySettingType();
Configuration.GetSection(nameof(MySettingType)).Bind(myConfig);
这都很酷..但是问题是为什么我必须使用它? 有什么可以解释的? 感谢您的帮助:)
解决方法
我将始终包含GetSection
。像这样的东西:Configuration.GetSection(nameof(MySettingType)).Get<MySettingType>();
但是您以后在myConfig
方法中真的需要ConfigureServices
吗?
如果没有,您也可以这样做:services.Configure<MySettingType>(Configuration.GetSection(nameof(MySettingType));
您可以找到有关Microsoft建议bind hierarchical configuration的其他示例。
,绑定选项时,假定T的结构与Configuration
相同。它不考虑类型名称。因此,如果要绑定由类型键入的配置的特定部分中的选项,则需要使用GetSection
,这将返回作用域为该部分的新ConfigurationSection对象。从那时起,同样的规则适用。
如果需要约定,可以编写一个扩展方法,该方法可以根据类型名称进行绑定。
public static T BindByTypeName<T>(this IConfiguration configuration)
where T : class,new()
{
return configuration.Bind<T>(typeof(T).Name);
}
您还可以将MySettingsType
与另一个AppSettings
包裹起来,以便您的选项与您的appsettings.json结构匹配。
class AppSettings
{
public MySettingsType MySettingsType { get; set; }
}
然后,您只需在根配置上调用Get<AppSettings>
。
Configuration.Get<AppSettings>().MySettingsType;