.NET Core Configuration is Simple

Written by igorlopushko | Published 2021/11/04
Tech Story Tags: csharp | net-core-configuration | cshart-top-story | csharp-tutorial | programming | coding | .net | tips-for-programmers

TLDR Let’s assume we want to create a simple Web API project. We need to add a connection string section to the **appsetting.json** file which is a default setup for the.NET Core Web API application. By default, appsettings.json and appsettings.Development.json files are created for the new project. It means that you could follow the pattern to create a configuration file for different environments and switch between them. Sometimes it happens that you need to add a configuration file with the custom name or path. It can be easily done in Program.cs file. You just need to call ConifugureAppConfiguration() method for the instance of IHostBuilder.via the TL;DR App

If you write code with .NET Core, one day, you will have to configure your application.

There is great documentation by Microsoft here.

I want to share with you what you really need to write an ordinary application. I’m going to use .NET Core 5. Let’s assume we want to create a simple Web API project. First of all, you have to understand that configuration itself is presented by the IConfiguration interface:

public interface IConfiguration
{
  string this[string key] { get; set; }
  IEnumerable<IConfigurationSection> GetChildren();
  IChangeToken GetReloadToken();
  IConfigurationSection GetSection(string key);
}

It is useful to know that an instance of the IConfiguration is already injected in Startup.cs file, and you can use the Configuration property to access the whole configuration:

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

public IConfiguration Configuration { get; }

Simple example

This might work fine if you need a connection string. Let’s use the appsetting.json file, which is a default setup for the .NET Core Web API application. Here is the code which is generated when you create this type of project:

{
  "Logging": {
    "LogLevel": {
      "Default": "Information",
      "Microsoft": "Warning",
      "Microsoft.Hosting.Lifetime": "Information"
    }
  },
  "AllowedHosts": "*"
}

Let’s assume we want to add a connection string section. appsetting.json file could now look like the following. The connection string here is just a sample. You might use the proper one for your database:

{
  "Logging": {
    "LogLevel": {
      "Default": "Information",
      "Microsoft": "Warning",
      "Microsoft.Hosting.Lifetime": "Information"
    }
  },
  "AllowedHosts": "*",
  "ConnectionStrings": {
    "DefaultConnection": "Server=YOURSERVERNAME; Database=YOURDATABASENAME; Trusted_Connection=True; MultipleActiveResultSets=true"
  }
}

Now we can access the connection string as follows. Let’s assume we have some UserService class that inherits the IUserService interface, and we would like to instantiate it with the connection string from the configuration:

public void ConfigureServices(IServiceCollection services)
{
  var defaultConnectionString = Configuration.GetConnectionString("DefaultConnection");
  services.AddScoped<IUserInterface>(x => new UserService(defaultConnectionString));
  // another code follows here  
}

Advanced example

However, it might be a bit overwhelming to use the whole configuration instance. The better approach is to introduce your own configuration class. Let’s assume you need to integrate a payment system into your application. Here are the steps you need to make. First of all, we need to add a new PaymentOptions section to the appsettings.json:

{
  "Logging": {
    "LogLevel": {
      "Default": "Information",
      "Microsoft": "Warning",
      "Microsoft.Hosting.Lifetime": "Information"
    }
  },
  "AllowedHosts": "*",
  "ConnectionStrings": {
    "DefaultConnection": "Server=YOURSERVERNAME; Database=YOURDATABASENAME; Trusted_Connection=True; MultipleActiveResultSets=true"
  },
  "PaymentOptions": {
    "Host": "https://host.com",
    "ApiKey": "hV79DIyA8WEH3AE2N1RDgVDHyEgTPnYC"
  }
}

We need to introduce the corresponding C# class:

public class PaymentOptions
{
  public string Host { get; set; }
  public string ApiKey { get; set; }
}

Now we can inject an instance of the PaymentOptions in the Startup.cs file:

public void ConfigureServices(IServiceCollection services) 

{
  // another code follows here
  services.Configure<PaymentOptions>(Configuration.GetSection(nameof(PaymentOptions)));
  // another code follows here
}

After that, we can use an instance of the PaymentOptions in any class constructor to access payment options through the default dependency injection mechanism.

How to set different values for different environments?

By default, appsettings.json and appsettings.Development.json files are created for the new project. It means that you could follow the pattern to create a configuration file for different environments and switch between them. The pattern for the configuration file name is appsettings.[Environment name].json.

You can set different values for the configuration properties in different files. To switch between different environment configurations, you have to set the ASPNETCORE_ENVIRONMENT environment variable.

How to add a custom JSON file?

Sometimes it happens that you need to add a configuration file with the custom name or path. It can be easily done in Program.cs file. You just need to call ConifugureAppConfiguration() method for the instance of IHostBuilder.

public static IHostBuilder CreateHostBuilder(string[] args) =>
  Host.CreateDefaultBuilder(args)
    // attach additional config JSON files
    .ConfigureAppConfiguration((hostingContext, config) =>
    {
      config.AddJsonFile("secret/appsettings.secret.json", optional: true);
      config.AddJsonFile("config/appsettings.json", optional: true, reloadOnChange: true);
    })
    .ConfigureWebHostDefaults(webBuilder => { webBuilder.UseStartup<Startup>(); });

There are a couple of important things to notice, using reloadOnChange property means that if a configuration was changed, the platform would reload it in runtime. Another thing is that the configuration file might be optional.

Summary

Configuration of the .NET Core application is very simple and can be done very fast. You have the power of the JSON files to create a configuration in a well-structured format and complete support of the .NET platform to use it in a natural way.


Written by igorlopushko | Programmer, Architect, Teacher
Published by HackerNoon on 2021/11/04