ConfigEx 2.1.0

library

I'd like to introduce a library for accessing app settings in the App.config and Web.config. Unlike standard ConfigurationManager, ConfigEx additionally allows reading configs of other assemblies used in the project. Moreover, it is strongly typed, has a mechanism of settings overriding, and allows applying automatic conversion of values.

First, let's take a look at the common way of using config settings. For example, App.config contains the following:

<configuration>
  <appSettings>
    <add key="StringSetting" value="Some string value" />
    <add key="IntSetting" value="123" />
  </appSettings>
</configuration>

In order to access these two settings, it is needed:

  1. Install the ConfigEx package from the NuGet: > Install-Package ConfigEx
  2. Create a new class derived from the ConfigBase. It should be declared in the same project where the target config is located. That means the new config class reads local settings - settings located in the same project.

The class for the example config above:

public class MyConfig : ConfigBase
{
    public virtual string StringSetting => Get<string>();
    public virtual int IntSetting => Get<int>();
}

The property name is used to locate the setting key. The generic type parameter of Get() specifies to what type string value should be converted. Of course, it is possible to set the default value and the custom setting key using the additional method parameters.

The ConfigEx reads settings only one time and caches them in the memory. If the value or the key itself is missing in the config, the Get() returns null.

It is recommended (but not mandatory) to make properties virtual, so it is possible easily fake them in the unit tests.

Now, let's add a date setting to the example. It requires a custom converter to be read correctly:

<configuration>
  <appSettings>
    <add key="CustomDateSetting" value="21082016" />
  </appSettings>
</configuration>

The custom converter should be implemented to automatically convert date value:

public class CustomConverter : TypeConverter
{
    public override T Convert<T>(string value)
    {
        // Convert only DateTime type.
        if (typeof(T) == typeof(DateTime))
        {
            return (T)(object)DateTime.ParseExact(
                value, "ddMMyyyy", CultureInfo.InvariantCulture);
        }
 
        // Use base conversion mechanism for all other types.
        return base.Convert<T>(value);
    }
}

The converter should be passed to the base constructor of the config class:

public class MyConfig : ConfigBase
{
    public MyConfig() : base(new CustomConverter()) {}
 
    public virtual DateTime CustomDateSetting => Get<DateTime>();
}

From now, when we read property CustomDateSetting, it returns strongly typed DateTime object, automatically converted by the CustomConverter.

In the same way, it is possible also to implement and override the default ConfigProvider (returns Configuration) and ConfigReader (implements the Get() method itself to read the Configuration). It might be useful if the settings are, for example, in the DB.

And the last handy feature - settings overriding. For example, a project contains an assembly that implements some functionality and can be configured in the App.config. Different applications that reference the assembly might want to configure it differently in their own config. A real example - an implementation of a logger that is reused in several projects.

How does it work: assembly has an App.config file and the settings like usual. It may or may not contain the value. In the config class the corresponding property should call the GetOverridden(). That's basically it.

<configuration>
  <appSettings>
    <add key="OverriddenSetting" value="Not overridden yet value" />
  </appSettings>
</configuration>
public class MyConfig : ConfigBase
{
    public virtual string OverriddenSetting => GetOverridden<string>();
}

When an external project (the main project that compiles into .exe, or the main project of ASP.NET website) uses MyConfig.OverriddenSetting it gets the value shown above. If the value should be overridden, the external project should define the setting with the same key OverriddenSetting in its own config.

In case of web projects that don't have .exe file and entry points, the main assembly should be marked with the MainConfigAssemblyAttribute in the AssemblyInfo.cs to help ConfigEx to find out where to look for the overridden settings.

In order to correctly read settings, make sure, that config files of the referenced assemblies are in place near the assembly's .dll.

The library works in all project types: class libraries, desktop, and console applications, ASP.NET projects.

An example of usage can be found on the GitHub project's page.

next post: A shared logger