The second way is a little bit better than the first one. Just use the GetValue method and be explicit about what type want to convert it to.
Like you can see, automatically converting String to Boolean is very good but still, it has lots of code repetition calling the GetSection method.
#3 AppSettings – GetValue inline
The third and more elegant way is to write all properties inline and in order, separated by a colon.
- [ApiController]
- [Route("[controller]")]
- public class Way3Controller : ControllerBase
- {
- private readonly IConfiguration _configuration;
-
- public Way3Controller(
- IConfiguration configuration)
- {
- _configuration = configuration;
- }
-
- [HttpGet]
- public bool Get()
- {
- return _configuration.GetValue<bool>("MySettings:Parameters:IsProduction");
- }
- }
You have to agree with me, that way is much better than the other two.
But we are still writing lots of String words on the GetValue method and injection the IConfiguration interface in the controller’s constructor.
Imagine if we have lots of controllers, we need to repeat this code across all controllers, and this is not a good programming practice.
#4 AppSettings – GetSection e Binding
The fourth way is to connect (like a binding) one class instance to a corresponding tag in the AppSettings.JSON file.
Let’s create a class called MySettingsConfiguration with the same properties above MySettings tag in the AppSettings.JSON file.
- public sealed class MySettingsConfiguration
- {
- public bool Log { get; set; }
- public string ConnectionStringId { get; set; }
- public Parameters Parameters { get; set; }
- }
-
- public sealed class Parameters
- {
- public bool IsProduction { get; set; }
- }
Now it’s just to configure the binding between a MySettingsConfiguration instance and the configuration section using the Bind method, check it out,
- [ApiController]
- [Route("[controller]")]
- public class Way4Controller : ControllerBase
- {
- private readonly MySettingsConfiguration _settings;
-
- public Way4Controller(
- IConfiguration configuration)
- {
- _settings = new MySettingsConfiguration();
- configuration.GetSection("MySettings").Bind(_settings);
- }
-
- [HttpGet]
- public bool Get()
- {
- return _settings?.Parameters?.IsProduction ?? false;
- }
- }
But we are still using the GetSection method, dependency injection of IConfiguration in the controller’s constructor. We can do better than that!
#5 AppSettings – IOptions
The next way to read the AppSettings.JSON file is by using the IOptions interface typing MySettingsConfiguration class that we created before.
- [ApiController]
- [Route("[controller]")]
- public class Way5Controller : ControllerBase
- {
- private readonly IOptions<MySettingsConfiguration> _configuration;
-
- public Way5Controller(
- IOptions<MySettingsConfiguration> configuration)
- {
- _configuration = configuration;
- }
-
- [HttpGet]
- public bool Get()
- {
- return _configuration.Value?.Parameters?.IsProduction ?? false;
- }
- }
Remember, to use it that way it’s necessary to perform a small configuration on the Startup.cs file.
- public void ConfigureServices(
- IServiceCollection services)
- {
-
- services.Configure<MySettingsConfiguration>(Configuration.GetSection("MySettings"));
-
- services.AddControllers();
- }
That is a better way to read the AppSettings.JSON file, but we are still using an ASP.NET CORE internal interface, in this case, the IOptions interface.
It could be interesting that all controllers and business classes don’t use ASP.NET CORE internal references.
#6 AppSettings – PRE-Binding
In my option, the best way to read the AppSettings.JSON file is to injection the MySettingsConfiguration class that we created before.
- [ApiController]
- [Route("[controller]")]
- public class Way6Controller : ControllerBase
- {
- private readonly MySettingsConfiguration _configuration;
-
- public Way6Controller(
- MySettingsConfiguration configuration)
- {
- _configuration = configuration;
- }
-
- [HttpGet]
- public bool Get()
- {
- return _configuration.Parameters.IsProduction;
- }
- }
This way is much more straightforward, and we don’t use any ASP.NET CORE internal interface.
To make this work, it’s necessary one configuration is in the Startup.cs file.
- public void ConfigureServices(
- IServiceCollection services)
- {
-
- var mySettings = new MySettingsConfiguration();
- new ConfigureFromConfigurationOptions<MySettingsConfiguration>(Configuration.GetSection("MySettings")).Configure(mySettings);
- services.AddSingleton(mySettings);
-
- services.AddControllers();
- }
That configuration seems too complex to understand, even more, if you need to repeat that code for other tags and classes.
To make it easy and not repeat any code, I created an Extension Method to encapsulate all these code blocks, and it becomes very easy to use it.
- public void ConfigureServices(
- IServiceCollection services)
- {
-
- services.AddConfiguration<MySettingsConfiguration>(Configuration, "MySettings");
-
- services.AddControllers();
- }
- public static class ConfigurationExtension
- {
- public static void AddConfiguration<T>(
- this IServiceCollection services,
- IConfiguration configuration,
- string configurationTag = null)
- where T : class
- {
- if (string.IsNullOrEmpty(configurationTag))
- {
- configurationTag = typeof(T).Name;
- }
-
- var instance = Activator.CreateInstance<T>();
- new ConfigureFromConfigurationOptions<T>(configuration.GetSection(configurationTag)).Configure(instance);
- services.AddSingleton(instance);
- }
- }
That’s it, thank you for reading, and I hope you enjoyed it.
Share and comment if you know other ways to read settings the AppSettings.JSON file.
Thank you 🙂