DEV Community

Cover image for Reading Configuration Values in Your ASP.NET Application
Chinonso Ikewelugo
Chinonso Ikewelugo

Posted on

Reading Configuration Values in Your ASP.NET Application

Prerequisites

  • Some knowledge of C# and ASP.NET

Introduction

When building our applications, we usually have some constants that are either used to handle the application setup, or are part of our application logic. We cannot necessarily hard-code these values where needed, because a change to such a value would require changes in all the files where the value is used. This is not very efficient or neat. The better way is to store these values in a configuration file, such as the appsettings.json file in our ASP.NET application. We can then read the values in our application, and any changes required would be made in just one location, the configuration file.

Reading Configuration Values from appsettings.json

So, how do we read configuration values from our appsettings.json? We will look at two ways we can do this.

The first is by making use of the configuration object directly. In .NET 5 and below, the configuration object is an instance of ConfigurationRoot, and is present in the Startup.cs by injecting the IConfinguration interface in the constructor.

public class Startup
{
    public Startup(IConfiguration configuration)
    {
        Configuration = configuration;

        decimal interestRate = configuration.GetSection("LoanSettings").GetValue<decimal>("InterestRate");
    }

    public IConfiguration Configuration { get; }
}
Enter fullscreen mode Exit fullscreen mode

In .NET 6 and above, the configuration object is an instance of ConfigurationManager, and is a property of the the application builder. So it can be accessed like so in the program.cs.

var builder = WebApplication.CreateBuilder(args);
var configuration = builder.Configuration;
Enter fullscreen mode Exit fullscreen mode

We can then use a number of methods on the configuration object to read our values. Say we had our appsettings.json structured like this:

{
  "EnableLoans": true,
  "LoanSettings": {
    "InterestRate": 0.07,
    "DefaultLoanTenure": 6
  }
}
Enter fullscreen mode Exit fullscreen mode

We can access the InterestRate value by calling GetSection on the configuration object, and chaining GetValue to it:

decimal interestRate = configuration.GetSection("LoanSettings").GetValue<decimal>("InterestRate");
Enter fullscreen mode Exit fullscreen mode

GetSection retrieves the section with the specified key, and GetValue retrieves the value with the specified key inside that section and converts it to the type specified.

To access our configuration values outside of the Program.cs or Startup.cs, we add the IConfiguration to the constructor of the classes in which we need the configurations.

 public class LoanService
 {
    private readonly IConfiguration _configuration;

    public LoanService(IConfiguration configuration)
    {
        _configuration = configuration;
    }
 }
Enter fullscreen mode Exit fullscreen mode

We can now make use of the configuration variable in the same way.

decimal interestRate = configuration.GetSection("LoanSettings").GetValue<decimal>("InterestRate");
Enter fullscreen mode Exit fullscreen mode

The problem with this method is that we're loading our application's entire configuration each time we need it, just to access some specific configurations. So, this is not very performance-friendly.

A better way would be to fetch only what we need and use it in the class. We can achieve this by creating a model for the section in our appsettings.json, with properties matching the names and types of the keys we have configured. We can then bind the configurations in the section to the model on application startup.

So, we could have a class matching the LoanSettings section of our appsettings.json like this:

public class LoanSettings
{
    public decimal InterestRate { get; set; }
    public decimal DefaultLoanTenure { get; set; }
}
Enter fullscreen mode Exit fullscreen mode

We can then bind this model to our LoanSettings configuration by calling the Configure method on our service collection.

builder.Services.Configure<LoanSettings>(configuration.GetSection("LoanSettings"));
Enter fullscreen mode Exit fullscreen mode

We can now use the configured instance of LoanSettings like this:

public class LoanService
{
    private readonly IOptions<LoanSettings> _loanSettings;

    public LoanService(IOptions<LoanSettings> loanSettings)
    {
        _loanSettings = loanSettings;
    }
}
Enter fullscreen mode Exit fullscreen mode

IOptions is used to retrieve configured instances of LoanSettings. The Value property of the IOptions holds the LoanSettings instance.

decimal interestRate = _loanSettings.Value.InterestRate;

We can alternatively inject the LoanSettings directly in our class constructor without wrapping it in IOptions, by adding it as a service after calling Configure on the service collection.

builder.Services.Configure<LoanSettings>(configuration.GetSection("LoanSettings"));
builder.Services.AddScoped(config => config.GetRequiredService<IOptions<LoanSettings>>().Value);
Enter fullscreen mode Exit fullscreen mode
public class LoanService
{
    private readonly LoanSettings _loanSettings;

    public LoanService(LoanSettings loanSettings)
    {
        _loanSettings = loanSettings;
    }
}
Enter fullscreen mode Exit fullscreen mode

We can now access the LoanSettings object directly:

decimal interestRate = _loanSettings.InterestRate;
Enter fullscreen mode Exit fullscreen mode

Conclusion

This is how we access and make use of configuration values in our application safely and efficiently.

Top comments (2)

Collapse
 
gravy17 profile image
Tofi Agbaje

Oh wow, didn't occur to me that you could inject sections in Services. That's so clean. Nice one

Collapse
 
chinonsoike profile image
Chinonso Ikewelugo

Yes, you can. Thanks chief!