For the past two and a half years as a Software Engineer at CQL, I have been steadily working on a project utilizing .NET Framework Web API, SQL Server, Angular, and Azure technologies. While I commonly use these technologies day-to-day, I’ve recently had the opportunity to dive into new .NET Core features and libraries from Microsoft for a client (we’re already up to version 3.1!).
Three Strong Configuration Strategies of .NET Core
One of the first things that I found that changed drastically with .NET Core is application configuration. Note: this document pertains to console apps. ASP.NET Core web apps may be configured slightly differently.
Microsoft provides several configuration strategies as part of .NET Core. The configuration system allows you to use as many as you like in a hierarchical fashion. I am going to focus on three of them: JSON files, user secrets, and environment variables.
Storing Configuration Files with JSON to Maximize App Development
Storing configuration in files inside the project is a natural and easy method of app configuration for development, and JSON is a great format for it. Many times, developers are using the same configuration settings, which means pulling from source control and running the app is optimal, with no individual setup on each developer machine. This is where the JSON configuration is nice to have. I can add all my non-sensitive information to the file, supplying default values where possible, push to Git, and everybody is happy.
Also, the JSON format is clean (especially compared to the old web.config files). Although you can use any file name you like, the standard is “appsettings.json”, created in the root of your project (remember to set Copy to Output Directory = Copy always on that file). Here’s my current appsettings.json file with a database connection string and API configuration:
Note that the password field is empty. I want to control access to the password and not have it stored out in my repo. Knowing where to configure the password leads us to user secrets,the next core App configuration.
Adding User Secrets to Secure Your User Directory
There are a couple of different ways to add user secrets. I use the Visual Studio (VS) UI, but you can also use the dotnet CLI, if you prefer. The main reason for adding user secrets is to ensure your data is stored on your local machine outside the project path and not included in source control.
To kick things off, you start by right-clicking on your project and choosing “Manage User Secrets”. If you haven’t already added the NuGet package, VS will ask if you want to install the required packages. Click “yes”, and it will proceed to add the Microsoft.Extensions.Configuration.UserSecrets
NuGet package to the project and add a <UserSecretsId>
element to your project file with a GUID for the secrets in this project. VS also opens a new file in the editor named secrets.json. This file is stored in %APPDATA%\Microsoft\UserSecrets\<GUID>\secrets.json
.
Note that the data in this file is not encrypted, but stored in your user directory. This means it relies on the OS to secure the contents. The secrets.json file is formatted exactly like the appsettngs.json file. Here’s what it looks like (sensitive information is not real):
There is now an API password configured and a connection string points to a different database server. The other fields do not need to be present, as they will be read from the JSON file. If you set up the configuration code correctly (I’ll show that later), the values shown here will override the values in the appsettings.json file.
Using Environment Variables to Configure Different Environments
The third configuration implementation is environment variables. Environment variables can be useful to configure different environments and are especially useful when configuring apps running in Docker. There are different ways to do that depending on the host (Windows, Linux, Docker, Azure, etc.), so I won’t get into how to set environment variables, except for in your Visual Studio development environment.
Now for some code. You will first have to add some NuGet packages:
And a little code:
ConfigurationBuilder
is going to do most of the work. The order of configurations added to the builder is the same order they will be used at runtime. The configurations added later will override the earlier ones.
Let’s get started. First, add the JSON file configuration by calling AddJsonFile()
. Next, we check an environment variable since we only want to use user secrets in a development environment. If so, we add our user secrets to the ConfigurationBuilder
. Then, we add our environment variables configuration. Note the “CONFIG_” parameter passed into AddEnvironmentVariables:
that tells the builder to look for environment variables that have a prefix of “CONFIG_”, ignoring all other environment variables. That prefix will then be removed before the configuration is applied. For local development, you can add environment variables to your launchSettings.json file:
In this instance, add NETCORE_ENVIRONMENT=Development
so the user secrets can configure when running locally Overriding the Api.BaseUrl
settings demonstrates how to format environment variable names (note the CONFIG_ prefix, and the use of a double underscore as a separator).
Finally, call the ConfigurationBuilder.Build()
method to create an IConfigurationRoot
instance. This instance could then be used to read configuration values directly. An even better idea is that we can bind the values to POCO’s and add them to the ServiceCollection (DI infrastructure). That’s exactly what the last two lines of code do.
Here’s what my POCO objects look like:
Notice that they map exactly to the configuration schema in the JSON files.
The configuration is then injected into properly configured services as an instance of IOptions<T>
:
New Configurations with .NET Core: A Welcome Change from Microsoft
In summary, I am liking the direction Microsoft took with configurations in .NET Core. With just a little knowledge of how to set up your project, you can have both a simple and flexible configuration scheme and a welcome change from the old XML configuration style. Some other configuration providers not discussed here are: Ini file, XML file, and Azure Key Vault. These are all available as NuGet packages.
Contact CQL Today for more Insights on .NET Core Configurations
Have questions or are interested in knowing more about .NET Core app configurations or other configuration providers from one of our talented, certified software developers? Contact us today.