C# – How to read a custom class from app.config with an automatic loader

It’s tedious to manually map settings from appSettings to your own class. You may have looked for ways to load your own custom class. The official documentation that explains how to do this is overly complicated. They would have you inheriting from ConfigurationSection, etc…, which is way too much effort.

Why bother with all of that manual, tedious code when you can create a reusable, automatic custom config loader with only a few lines of code?

In this article, I’ll show you the simplest way to add your own custom class to app.config and how to automatically load it.

1 – Add the custom class – WeatherClientConfig

The first step is to create your custom class and put all the public properties you need.

public class WeatherClientConfig { public bool IsEnabled { get; set; } public string WeatherAPIUrl { get; set; } public string Timeout { get; set; } }
Code language: C# (cs)

2 – Add the automatic config loader class

The following CustomConfigLoader class is an automatic config loader. By implementing IConfigurationSectionHandler, when you use ConfigurationManager.GetSection(), it uses CustomConfigLoader.Create() to load the section.

To automatically load the custom class, it uses uses reflection to match the target type with the specified section name. Then it uses XmlSerializer to automatically deserialize the section XML into the target type.

using System; using System.Configuration; using System.Linq; using System.Xml; using System.Xml.Serialization; namespace WeatherClient { public class CustomConfigLoader : IConfigurationSectionHandler { public object Create(object parent, object configContext, XmlNode section) { if (section == null) { throw new ArgumentNullException($"XMLNode passed in is null."); } var type = AppDomain.CurrentDomain.GetAssemblies() .SelectMany(a => a.GetTypes()) .FirstOrDefault(t => t.Name == section.Name); if (type == null) { throw new ArgumentException($"Type with name {section.Name} couldn't be found."); } XmlSerializer ser = new XmlSerializer(type, new XmlRootAttribute(section.Name)); using (XmlReader reader = new XmlNodeReader(section)) { return ser.Deserialize(reader); } } } }
Code language: C# (cs)

3 – Add the custom class in app.config

You need to add a section in configSections, then you can add an XML representation of your custom class in app.config. Take a look at the highlighted sections in the app.config below:

Note: If configSections is missing, add the whole configSections node. If it’s already in there, just add the section node within the configSections node.

<?xml version="1.0" encoding="utf-8"?> <configuration> <configSections> <section name="WeatherClientConfig" type="WeatherClient.CustomConfigLoader, WeatherClient" /> </configSections> <startup> <supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.7.2" /> </startup> <WeatherClientConfig> <IsEnabled>true</IsEnabled> <WeatherAPIUrl>https://localhost:12345</WeatherAPIUrl> <Timeout>5000</Timeout> </WeatherClientConfig> </configuration>
Code language: HTML, XML (xml)

The section node has two attributes.

nameThe section name. Make sure this matches your custom class name.

This is what you pass in to ConfigurationManager.GetSection().

Also, the CustomConfigLoader uses this to automatically lookup the type to load.

In this article, the custom class name is WeatherClientConfig. That’s why the section name is also WeatherClientConfig.
typeThe custom config loader type.

This may be confusing. You might expect this to be the custom class type, but it’s not. It’s the type of the custom config loader that you want handling the loading of this section.

This has the format: “Namespace.ClassName, AssemblyName”. In this article, the custom config loader is WeatherClient.CustomConfigLoader and it’s located in the WeatherClient assembly, hence, the type = “WeatherClient.CustomConfigLoader, WeatherClient”.

This part is easy to get wrong, because it’s confusing that you have to point to the custom config loader class. If you’re having trouble getting this working, doublecheck that you’re pointing to the right assembly where the custom config loader class is located.

4 – Use the custom config

Now that all the pieces are in place, you can load the config and use it simply by calling ConfigurationManager.GetSection(), passing in the custom section name.

In this case, I am simply loading the config in a console app and writing out the values.

static void Main(string[] args) { var config = (WeatherClientConfig)ConfigurationManager.GetSection(nameof(WeatherClientConfig)); Console.WriteLine(config.WeatherAPIUrl); Console.WriteLine(config.IsEnabled); Console.WriteLine(config.Timeout); }
Code language: C# (cs)

This outputs the following, exactly what you would expect, since it’s what’s in the app.config:

https://localhost:12345 True 5000
Code language: plaintext (plaintext)

Leave a Comment