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 <WeatherClientConfig> node matches the custom class you added in step one.

The <section> node basically means: “I want to use this config loader to load this custom XML section.” Take a look at the <section> node again:

<section name="WeatherClientConfig" type="WeatherClient.CustomConfigLoader, WeatherClient" />
Code language: HTML, XML (xml)

So this means: “I want to use the WeatherClient.CustomConfigLoader class from assembly WeatherClient to load custom section WeatherClientConfig.”

First, name=”WeatherClientConfig” is the name of the custom XML section you added (<WeatherClientConfig>). This gets passed to CustomConfigLoader.Create(…) as the XmlNode section parameter.

If the name doesn’t match the custom XML section name you added, you’ll get an error like System.Configuration.ConfigurationErrorsException: Configuration system failed to initialize. So make sure it matches.

Second, type=”WeatherClient.CustomConfigLoader, WeatherClient” is the type info of the custom config loader that you added in step two. It’s in this format: “Namespace.ClassName, AssemblyName”.

If the type or assembly name don’t match, you’ll get an error like System.Configuration.ConfigurationErrorsException: An error occurred creating the configuration section handler… . Be sure to doublecheck your type names and assembly names.

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)

Code repository

The code shown here is available in this public repository: https://github.com/makolyte/AppConfigLoaderExample.

2 thoughts on “C# – How to read a custom class from app.config with an automatic loader”

  1. Is there a downloadable working example? This doesn’t work for me. I keep getting an error. I did everything the same except used the work Setting instead of Weather.

    System.Configuration.ConfigurationErrorsException: ‘An error occurred creating the configuration section handler for SettingsClientConfig: Could not load file or assembly ‘SettingsClient’ or one of its dependencies. The system cannot find the file specified. ( line 4)’

    Inner Exception
    FileNotFoundException: Could not load file or assembly ‘SettingsClient’ or one of its dependencies. The system cannot find the file specified.

    Line 4 is the reference to the custom objects

    If there is a downloadable working example I may be able to figure this out, but I don’t see where I’ve done anything different than what you have here.

    Reply
    • I get this error when I put the wrong assembly name in the config. You have “SettingsClient” as the assembly name in the config. Check if this matches your project’s assembly name.

      My assembly name is “WeatherClient”, so I have that in the config (bolded part):
      <configSections>
          <section name="WeatherClientConfig" type="WeatherClient.CustomConfigLoader, WeatherClient" />
      </configSections>

      Fixing the configured assembly name should solve the problem for you. Nevertheless, as you requested, I put the working code in a public repo here: https://github.com/makolyte/AppConfigLoaderExample

      Thank you for asking about this – I updated the page to try to better explain the possible errors you might run into with the configuration.

      Reply

Leave a Comment