Strongly Typed Configuration Settings in ASP.NET Core Part II

Written by Khalid Abuhakmeh
4
This post is days old.

Rick Strahl wrote an amazing post about getting strongly typed configuration objects in ASP.NET Core. The one gripe I have about the approach, by no fault of his, is the proliferation of the interface IOptions<T>. Seeing the abstraction in my code feels leaky. This post will show you how to take the strongly typed configuration and directly register it with the ServicesCollection in your ASP.NET Core applications.

The Alternative Solution

Let’s take a simple class, which will be hydrated via our strongly typed object. The passing of the BankSettings object is an optional step I decided to take. I pass the settings into the constructor as the Bank object will be a Singleton in my application and I don’t want anyone (especially me) accidentally setting the Bank properties.

public class Bank
{
    public Bank(BankSettings config)
    {
        if (config == null) throw new ArgumentNullException(nameof(config));

        AccountNumber = config.AccountNumber;
        Name = config.Name;
    }

    public Guid AccountNumber { get; protected set; }
    public string Name { get; protected set; }
}
// our serialization target
public class BankSettings
{
    public Guid AccountNumber { get; set; }
    public string Name { get; set; }
}

The settings in appSettings.json looks like this.

{
  "Bank": {
    "AccountNumber": "765577c4-d5d1-43a0-82a0-14642b23ed81",
    "Name": "Central Bank"
  },
  "Data": {
    "Marten": {
      "ConnectionString": "host=localhost;database=bank;password=marten;username=marten"
    }
  },
  "Logging": {
    "IncludeScopes": false,
    "LogLevel": {
      "Default": "Debug",
      "System": "Information",
      "Microsoft": "Information"
    }
  }
}

Finally, let’s serialize the settings and push the hydrated Bank object into our ServicesCollection.

public static class BankExtensions
{
    public static IServiceCollection AddBank(this IServiceCollection services, IConfigurationRoot configuration)
    {
        var section =
            configuration.GetSection("Bank");
        // we first need to create an instance
        var settings = new BankSettings();
        // then we set the properties 
        new ConfigureFromConfigurationOptions<BankSettings>(section)
            .Configure(settings);
        // then we register the instance into the services collection
        services.AddSingleton(new Models.Bank(settings));

        return services;
    }
}

If you followed the post correctly, you should be able to inject the object into your application models without that pesky IOptions<T> interface.

asp.net core strongly typed app settings

Suggested reading

Comments