Problem
How do we read configuration settings from various sources and use them throughout our application?
Solution
Starting from the Empty Project from a previous post, add appsettings.json and appsettings.Development.json files in your project.
-
- {
- "Section1": {
- "SettingA": "ValueA",
- "SettingB": "ValueB"
- },
- "Section2": {
- "SettingC": "ValueC"
- }
- }
-
- {
- "Section1": {
- "SettingA": "Dev_ValueA"
- },
- "Section2": {
- "SettingC": "Dev_ValueC"
- }
- }
Then, read configuration settings in the constructor for Startup class.
- public static IConfiguration Config { get; private set; }
-
- public Startup(
- IConfiguration config)
- {
- Config = config;
- }
Then, add option services in ConfigureServicees() method of Startup class.
- public void ConfigureServices(
- IServiceCollection services)
- {
-
- services.AddOptions();
- services.Configure(Config);
- }
Finally, inject settings as IOptions interface where T is your POCO.
- public class HelloWorldMiddleware
- {
- private readonly RequestDelegate next;
- private readonly AppSettings settings;
-
- public HelloWorldMiddleware(
- RequestDelegate next,
- IOptions options)
- {
- this.next = next;
- this.settings = options.Value;
- }
-
- public async Task Invoke(HttpContext context)
- {
- var jsonSettings = JsonConvert.SerializeObject(this.settings);
- await context.Response.WriteAsync(jsonSettings);
- }
- }
Running the sample application gives you the following output.
Discussion
ASP.NET Core has a simple mechanism to read application settings from various sources like JSON file, Environment variables, or even custom data sources. It is also simple to use the settings, thanks to Dependency Injection.
Although it seems like magic (how did your settings get loaded!), ASP.NET Core 2.0 hides the adding of configuration settings behind CreateDefaultBuilder() method of WebHost, in Program.cs. IConfiguration is then added to the service container and is available in the rest of your application. We used this in Startup to add options. To see this, replace the BuildWebHost() method in Program.cs and run the program. You’ll get the same result.
- public static IWebHost BuildWebHost(string[] args)
- {
- return WebHost.CreateDefaultBuilder(args)
- .ConfigureAppConfiguration((context, builder) =>
- {
- var env = context.HostingEnvironment;
-
- builder.AddJsonFile("appsettings.json",
- optional: true, reloadOnChange: true)
- .AddJsonFile($"appsettings.{env.EnvironmentName}.json",
- optional: true, reloadOnChange: true);
-
- if (env.IsDevelopment())
- {
- var appAssembly = Assembly.Load(
- new AssemblyName(env.ApplicationName));
- if (appAssembly != null)
- {
- builder.AddUserSecrets(appAssembly, optional: true);
- }
- }
-
- builder.AddEnvironmentVariables();
-
- if (args != null)
- {
- builder.AddCommandLine(args);
- }
- })
- .UseStartup<Startup>()
- .Build();
- }
In the solution above, two JSON file sources are provided. The important thing to remember is that these sources are read sequentially and overwrite the settings from the previous source. You could see this in the solution above. The output shows Setting B’s value coming from first settings file whereas the other settings are being overwritten by the second settings file.
Note that a public static property holds IConfiguration instance so that it can be used throughout the application like -
- var valueA = Config["Section1:SettingA"];
However, a better approach also exists to read the settings, i.e., to read the settings into a typed POCO class and then inject it as a dependency into middleware, controllers etc. In the solution above, I’ve used the middleware from a previous post to demonstrate this pattern.
You can also have POCO classes for various sections in the settings file and read them using GetSection() method on IConfiguration.
- services.Configure(Config.GetSection("Section1"));
It’s also possible to populate the settings in code using overload of IServiceCollection.Configurethat accepts strongly typed lambda.
- services.Configure(options =>
- {
- options.Section1.SettingA = "SomeValue";
- });
Source Code
GitHub