Ben McIntyre
Ben McIntyre

Reputation: 1968

Strongly Typed Configuration Settings in .NET Core 2 Console Application

I'd like to access the appsettings.json file (and perhaps other config files) using strongly typed classes. There is a lot of info out there about doing so in .NET Core 1 (eg. https://weblog.west-wind.com/posts/2016/may/23/strongly-typed-configuration-settings-in-aspnet-core), but next to nothing about .NET Core 2.

In addition, I'm building a console app, not ASP.NET.

It appears that the configuration API has completely changed in .NET Core 2. I can't work it out. Anyone?

EDIT: I think perhaps the Core 2 docs have not caught up yet. Example: https://learn.microsoft.com/en-us/dotnet/api/microsoft.extensions.configuration.configurationbinder?view=aspnetcore-2.0 indicates, you would think, that ConfigurationBinder exists in .NET Core 2, but an object browser search of Microsoft.Extensions.Configuration and Microsoft.Extensions.Options reveals nothing.

I have used the NuGet Console to

Upvotes: 3

Views: 2990

Answers (1)

Ben McIntyre
Ben McIntyre

Reputation: 1968

Thanks to Martin Ullrich for that observation, which led to the solution. There were several things at play here:

  • i'm rusty with DLL-level references because the old style 'references' (as opposed to the new 'dependencies' in .NET Core) hid all that
  • i was assuming that installing the NuGet Microsoft.Extensions.Configuration package would install the child namespace DLLs. In fact there are many packages for those in the NuGet Gallery (see here). The NuGet console doesn't tell you what DLLs you're getting specifically, but you can see them in the Solution Browser once they're installed: enter image description here
    AND, searching for ConfigurationBinder in the API Browser yields nothing, I'm guessing because it's part of the extension library.
  • Rick Strahl did mention it in his post (linked in the question), but I still missed it: the Bind method, for example, looks a lot like a static method on ConfigurationBinder. However in reality it's an extension method. As such, it magically appears when the NuGet package is installed. This makes us rely heavily on the docs, which I haven't quite worked out yet.

So, in summary, the solution was to:

  • Install-Package Microsoft.Extensions.Configuration.Binder -Version 2.0.0
  • Install-Package Microsoft.Extensions.Configuration.Json-Version 2.0.0

the first giving the .Bind method, and the second the .SetBasePath and .AddJsonFile methods.

I'll add the final code here in a day or so once I perfect it.

EDIT:

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;
}

Note that the code above is actually for a YAML configuration file. You will need to tweak the single line that load the YAML to use JSON. I haven't tested these, but they should be close:

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

Upvotes: 6

Related Questions