ConfigurationSection ohne viel drum rum

6. Oktober 2010

Eine ConfigurationSection zu erstellen, kann schon ein wenig aufhalten. Was mir aber besonders missfällt: die Klasse mit den Daten muss von der abstrakten Klasse ConfigurationSection ableiten – kann also nicht in einer Vererbungshierarchie stecken.
Die folgende Klasse nutzt eine beliebige Entitäten-Klasse (die nicht von ConfigurationSection abgeleitet sein muss), um sie aus der Konfigurationsdatei über den normalen ConfigurationManager zu befüllen. Neue Konfigurationselemente kann ich einfach als Auto-Properties dranhängen und in der app.config oder web.config eintragen – mehr ist nicht nötig.

public class ConfigReader : ConfigurationSection
{
    private static object current;
    private static Type currentType;
    private static object sync = new object();
        
    protected override void DeserializeSection(System.Xml.XmlReader reader)
    {
        var serializer = new XmlSerializer(currentType);
        current = serializer.Deserialize(reader);
    }
 
    public static TResult GetConfig<TResult>() 
            where TResult : new()
    {
        lock (sync)
        {
            currentType = typeof(TResult);
            ConfigurationManager.GetSection(currentType.Name);
            return (TResult)(current ?? new TResult());
        }
    }
}

Die Nutzung ist auch denkbar einfach:

var result = ConfigReader.GetConfig<MySectionClass>();

Der Name der Konfigurationssektion wird durch den Klassennamen des generischen Parameters für GetConfig angegeben. Der Aufruf von GetConfig sorgt für eine Deserialisierung der Klasse aus der Konfigurationsdatei und zur Initialisierung der statischen Variablen (konkurrierende Zugriffe werden durch das lock-Statement verhindert).

In der app.config werden alle so geladenen Sektionen auf ConfigReader gemapped:

<configSections>
  <section name="MySectionClass" type="Config.ConfigReader, Config"/>
  <section name="MyOtherSection" type="Config.ConfigReader, Config"/>
</configSections>

Beachten sollte man aber, dass die Validatoren für Konfigurationsklassen auf diesem Weg nicht eingesetzt werden können.