Home > .NET allgemein > Erstellen von benutzerdefinierten Konfigurationsabschnitten mit IConfigurationSectionHandler

Erstellen von benutzerdefinierten Konfigurationsabschnitten mit IConfigurationSectionHandler

Im folgenden wird gezeigt, wie mit Hilfe des Interfaces IConfigurationSectionHandler benutzerdefinierte Bereiche aus der app.config ausgelesen werden.

Aufbau, Sinn und Zweck von Konfigurationsdateien ist in den Online und Printmedien schon ausreichend dokumentiert. Deshalb will ich gleich auf das Erweitern der app.config um eigene, benutzerdefinierte Bereiche eingehen. Die app.config wurde so gekürzt, dass nur noch die eigene Sektion vorhanden ist. Im Bereich werden die einzelnen Sektionen aufgelistet. In diesem Beispiel ist es nur eine Sektion mit dem frei wählbaren, aber eindeutigen Namen mySection. Im Attribute type ist der Verweis auf eine Klasse, die das Interface IConfigurationSectionHandler implementieren muß. Dazu später mehr. Die Elemente der eigenen Sektion beginnen ab Zeile 6. Die darauf folgende XML-Struktur wurde von mir frei und willkürlich gewählt. Es ist eine Auflistung von drei Objekten.

<?xml version="1.0" encoding="utf-8" ?>
<configuration>
  <configSections>
    <section name="mySection"
             type="MySectionHandler.MyConfigurationSectionHandler, MyConfigurationSectionHandler"/>
  </configSections>
  <mySection>
    <values>
      <value valueAttribute="valAtt01">
        <identifier>1</identifier>
        <settingValue>
          <newValue>11.1</newValue>
          <oldValue>1.1</oldValue>
        </settingValue>
      </value>
      <value valueAttribute="valAtt02">
        <identifier>2</identifier>
        <settingValue>
          <newValue>22.2</newValue>
          <oldValue>2.2</oldValue>
        </settingValue>
      </value>
      <value valueAttribute="valAtt03">
        <identifier>3</identifier>
        <settingValue>
          <newValue>33.3</newValue>
          <oldValue>3.3</oldValue>
        </settingValue>
      </value>
    </values>
  </mySection>
</configuration>

Wie gelangt man jetzt an diese XML-Daten? Von zentraler Bedeutung ist die Klasse System.Configuration.ConfigurationManager. Über die statische Methode GetSection(string sectionName) werden die Daten der benannten Sektion angefordert. Allerdings bekommt man nicht direkt den XmlNode zurück. Sondern es wird die Klasse geladen, die im oberen Bereich unter

angegeben wurde. Diese Klasse muß das Interface IConfigurationSectionHandler implementiert haben. Das Interface hat nur eine Methode; object Create(object parent, object configContext, XmlNode section). Der Aufruf von ConfigurationManager.GetSection(“mySection”) bewirkt nun, dass über das Interface die Methode Create() aufgerufen wird. Als dritter Parameter wird das XmlNode übergeben. Es liegt jetzt ganz in der Hand des Programmierers, dieses XmlNode auszuwerten und typsicher umzuwandeln. In diesem Beipiel habe ich die Klasse SectionValue erzeugt, die nur dazu dient, in den Properties die Werte aufzunehmen.

ClassDiagram

Das Ergebnis der Auswertung wird als typsichere Auflistung an den Aufrufer von Create() zurückgeliefert.

class MyConfigurationSectionHandler : IConfigurationSectionHandler
{
  public object Create(object parent, object configContext, XmlNode section)
  {
    List<SectionValue> sectionValueList = new List<SectionValue>();
    XmlNodeList nodeList = section.SelectNodes(@"//value");
    foreach (XmlNode node in nodeList)
    {
      SectionValue sectionValue = new SectionValue();
      sectionValue.Id = XmlConvert.ToInt32(node.SelectSingleNode(@"identifier").InnerText);
      sectionValue.Attribute = node.Attributes["valueAttribute"].Value;
      sectionValue.OldValue = XmlConvert.ToDouble(node.SelectSingleNode(@"settingValue/oldValue").InnerText);
      sectionValue.NewValue = XmlConvert.ToDouble(node.SelectSingleNode(@"settingValue/newValue").InnerText);
      sectionValueList.Add(sectionValue);
    }
    return sectionValueList;
  }
}

Wurde einmal die ConfigurationSectionHandler-Klasse erstellt, ist es ein leichtes die gewünschten Informationen aus der Konfigurationsdatei auszulesen.

List<SectionValue> sectionValueList =
ConfigurationManager.GetSection("mySection") as List<SectionValue>;

Es soll an dieser Stelle auch nicht verschwiegen werden, dass die Schnittstelle IConfigurationSectionHandler seit dem .NET Framework Version 2.0 als veraltet gilt. Statt dessen sollten von der Klasse ConfigurationSection abgeleitet werden. Hierzu werde ich noch ein Beispiel liefern. Auch muss beachtet werden, dass die Klasse, die das Interface IConfigurationSectionHandler implementiert, threadsicher und zustandsfrei ist. Create() muss also entsprechend erweitert werden, damit diese Methode von mehreren Threads aufgerufen werden kann.

Advertisements
  1. No comments yet.
  1. No trackbacks yet.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

%d bloggers like this: