了解与 .NET Core 中的 appsettings 绑定相关联的行为的问题
Issue understanding a behaviour linked to appsettings binding in .NET Core
我遇到了一个奇怪的问题,我似乎无法使用 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文件中的key同名,匹配class是使用属性,都是public。
配置也位于 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
,这将 return 一个新的 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;
我遇到了一个奇怪的问题,我似乎无法使用 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文件中的key同名,匹配class是使用属性,都是public。 配置也位于 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
,这将 return 一个新的 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;