.NET Core 2控制台应用程序中的强类型配置设置

3
我希望使用强类型的类来访问appsettings.json文件(以及其他配置文件)。在.NET Core 1中有很多关于如何做到这一点的信息(例如:https://weblog.west-wind.com/posts/2016/may/23/strongly-typed-configuration-settings-in-aspnet-core),但是关于.NET Core 2的几乎没有。
此外,我正在构建一个控制台应用程序,而不是ASP.NET。
看起来,在.NET Core 2中,配置API已经完全改变了。我无法理解它。有人可以帮忙吗?
编辑:我认为Core 2文档还没有跟上。例如:https://learn.microsoft.com/en-us/dotnet/api/microsoft.extensions.configuration.configurationbinder?view=aspnetcore-2.0显示,您会认为ConfigurationBinder存在于.NET Core 2中,但是在Microsoft.Extensions.Configuration和Microsoft.Extensions.Options的对象浏览器搜索中找不到任何内容。
我已经使用NuGet控制台进行了以下操作:
  • Install-Package Microsoft.Extensions.Options -Version 2.0.0
  • Install-Package Microsoft.Extensions.Configuration -Version 2.0.0

1
ConfigurationBinderMicrosoft.Extensions.Configuration.Binder NuGet 包中。 - Martin Ullrich
1个回答

6

感谢Martin Ullrich的观察,这导致了问题的解决。这里有几个因素起了作用:

  • 因为旧式的“引用”(而不是.NET Core中的新“依赖项”)隐藏了所有这些内容,所以我对DLL级别的引用有点生疏。
  • 我假设安装NuGet Microsoft.Extensions.Configuration包会安装子命名空间DLL。实际上,在NuGet Gallery中有许多这样的包(请参见此处)。 NuGet控制台不会告诉您具体获取了哪些DLL,但一旦安装,您可以在解决方案浏览器中看到它们: enter image description here
    并且,在API浏览器中搜索ConfigurationBinder什么也找不到,我猜想这是扩展库的一部分。
  • Rick Strahl在他的帖子(链接在问题中)中提到了它,但我仍然错过了:例如,Bind方法看起来很像ConfigurationBinder上的静态方法。但实际上它是一个扩展方法。因此,当NuGet包被安装时,它会神奇地出现。这使我们严重依赖文档,但我还没有完全弄清楚。

因此,总的来说,解决方案是:

  • 安装 Microsoft.Extensions.Configuration.Binder 版本为 2.0.0 的包
  • 安装 Microsoft.Extensions.Configuration.Json 版本为 2.0.0 的包

第一个包提供了 .Bind 方法,第二个包提供了 .SetBasePath 和 .AddJsonFile 方法。

我稍后会在这里添加最终代码,一旦我完善它。

编辑:

public class TargetPhoneSetting {
    public string Name { get; set; } = "";
    public string PhoneNumber { get; set; } = "";
}

public class AppSettings {
    public List<TargetPhoneSetting> TargetPhones { get; set; } = new List<TargetPhoneSetting>();
    public string SourcePhoneNum { get; set; } = "";
}

public static AppSettings GetConfig() {
    string environment = Environment.GetEnvironmentVariable("ASPNETCORE_ENVIRONMENT");

    var builder = new ConfigurationBuilder()
        .SetBasePath(System.IO.Directory.GetCurrentDirectory())
        .AddYamlFile("appsettings.yml", optional: false)
        ;
    IConfigurationRoot configuration = builder.Build();

    var settings = new AppSettings();
    configuration.Bind(settings);

    return settings;
}

请注意,上面的代码实际上是用于YAML配置文件的。您需要调整加载YAML的单行代码以使用JSON。我没有测试这些,但它们应该很接近:
JSON:
{
  "SourcePhoneNum": "+61421999999",

  "TargetPhones": [
    {
      "Name": "John Doe",
      "PhoneNumber": "+61421999888"
    },
    {
      "Name": "Jane Doe",
      "PhoneNumber": "+61421999777"
    }
  ]
}

YAML:

SourcePhoneNum: +61421999999
TargetPhones:
    - Name: John Doe
      PhoneNumber: +61421999888
    - Name: Jane Doe
      PhoneNumber: +61421999777

同时添加支持的 appsettings.json 将不胜感激。谢谢。 - granadaCoder
添加了示例文件。 - Ben McIntyre
好的,这帮助我解决了一些神秘问题。 "public List<TargetPhoneSetting> TargetPhones" 是有用的代码行。它必须是List(而不是ICollection或IEnumerable)......以便于实例化或其他什么。我在这里找到了一个类似的评论:https://weblog.west-wind.com/posts/2016/May/23/Strongly-Typed-Configuration-Settings-in-ASPNET-Core,请查找Sean Fackrell的评论。 - granadaCoder
很好的发现,我记得我也花了一些时间才意识到这一点。参考评论是:Sean Fackrell - “如果有人碰巧遇到这个问题。在配置POCO中,您不能像正常的JSON反序列化一样使用'IEnumerable'或'IList'。 如果这样做,当您解析IOptions时,您将获得InvalidOperation异常。 您必须使用List或可能是可构造类型。” - Ben McIntyre

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接