了解与 .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;