Configuration Source vs Configuration Provider
Tags: dotnet, aspnetcore, csharp, beginners
Published: 2023-09-14 09:31:53


> This is part 1 of the series I intend to write about getting onboarded with configuration in ASPNETCORE. I will try to post the follow up articles soon


Before we actually talk about configuration in ASPNETCORE, it is important to address the Configuration Source and the Configuration Provider. We try to do that here

## Configuration Source

Configuration Source is the one which will act as the "input" to configure our application. It could be a json file, command line argument, an environment variable, the dotnet user secrets or it could even be an external config store - [AWS Parameter Store](https://docs.aws.amazon.com/systems-manager/latest/userguide/systems-manager-parameter-store.html) or even a SQL database. 

We all are familiar with the `appsettings.json` which gets shipped by default when we ask for a ASPNET Core web application scaffold. This then is a _configuration source_, where you would define the configuration to be used within your application as key value pairs.

> The only important thing to stress here is that the configuration source is anything where we specify any "_settings/configurations_" with their "_values_" which we can feed in as a "_configuration_" to our application

## Configuration Provider

Having gotten the configuration source out of our way now, its quiet easy to understand the concept of a configuration provider.

`var builder = WebApplication.CreateBuilder(args);`

`CreateBuilder` is kind of responsible to configure logging, set up the dependency injection container, configure a default host and also make available the default configuration sources to our application. The `CreateBuilder `is what makes us available the default "**host**". Using the default host object, we can also add more _configuration sources_ to it using the extensions provided by the ASPNETCORE framework.

Well, the first thing you would do is to define a configuration source (lets say it is a json file - you have all your configurations and their values in it) but then you must make the ASPNETCORE know of it in order for it to be available in your application.

Comes in the _Configuration Provider_ . It will "load" a specific configuration source and then make it available in your application, in its most basic form through `builder.Configuration` (more on it later)

Some of the default configuration providers by ASPNETCORE are Command-Line Configuration Provider, Environment variables configuration provider, JSON configuration provider. When we say default, it means ASPNETCORE will automatically handle them for us we need not do anything.

Following is a snippet from [here](https://github.com/dotnet/runtime/blob/6149ca07d2202c2d0d518e10568c0d0dd3473576/src/libraries/Microsoft.Extensions.Hosting/src/HostingHostBuilderExtensions.cs#L229-L256) . This is what is happening behind the scenes when ASPNETCORE is wiring up a default builder for you . Also notice, the order in which it loads the default configurations sources through their respective providers . So in the most vanilla form, any configuration provided by the command line arguments would override the ones before i.e. if you have a config key `isKanelbulle ` set as `false ` in your `appsetting.json` and while running the application, you pass in the same as an command line argument `isKanelbulle ` set to `true`, the **true** overrides the **false** value set in the json file

```cs
  appConfigBuilder.AddJsonFile("appsettings.json", optional: true, reloadOnChange: reloadOnChange)
                    .AddJsonFile($"appsettings.{env.EnvironmentName}.json", optional: true, reloadOnChange: reloadOnChange);

            if (env.IsDevelopment() && env.ApplicationName is { Length: > 0 })
            {
                try
                {
                    var appAssembly = Assembly.Load(new AssemblyName(env.ApplicationName));
                    appConfigBuilder.AddUserSecrets(appAssembly, optional: true, reloadOnChange: reloadOnChange);
                }
                catch (FileNotFoundException)
                {
                    // The assembly cannot be found, so just skip it.
                }
            }

            appConfigBuilder.AddEnvironmentVariables();

            AddCommandLineConfig(appConfigBuilder, args);
```


Putting it together now,

Say you have a json file as the configuration source - lets call it `MyDefaultConfigurations.json` . Then to make it available in the application, you would instruct the default json configuration provider of ASPNETCORE to "load" it.

`builder.Configuration.AddJsonFile("MyDefaultConfigurations.json",
optional: true,reloadOnChange: true);`

OBS - `appsettings.json` and `appsettings.{Environment}.json` are loaded by default, you don't have to register them explicitly as done above

Also an important thing to consider here is - in addition to the default configuration providers, you can build your own custom configuration providers as well. 

A use case of this would be - say you have an external API which is responsible to give you some configurations after running a complex logic. 

This then would become your configuration source. ASPNETCORE would obviously be unaware of this and none of the default providers would know how to handle it. This is then a good candidate for you to write your custom config provider which say would make a REST call to this service of yours to get the configuration and make it available in your application. There is already a good documentation on how to implement your custom configuration provider, link below.

Please feel free to correct :)

References

[default-application-configuration-sources](https://learn.microsoft.com/en-us/aspnet/core/fundamentals/configuration/?view=aspnetcore-7.0#default-application-configuration-sources)

[Custom Configuration Provider Example](https://learn.microsoft.com/en-us/aspnet/core/fundamentals/configuration/?view=aspnetcore-7.0#custom-configuration-provider)

---

<!--Post 2 -->