Laden von Properties.Settings aus einer anderen Datei zur Laufzeit

Gibt es eine Möglichkeit, Einstellungen aus einer anderen als der Standarddatei zu laden?App.config Datei zur Laufzeit? Ich möchte dies tun, nachdem die Standardkonfigurationsdatei geladen wurde.

Ich verwende dasSettings.Settings GUI in Visual Studio zum Erstellen meinerApp.config Datei für mich. Die Konfigurationsdatei sieht dann so aus:

    <?xml version="1.0" encoding="utf-8" ?>
    <configuration>
        <configSections>
            <sectionGroup name="applicationSettings" type="System.Configuration.ApplicationSettingsGroup, System, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" >
        <section name="SnipetTester.Properties.Settings" type="System.Configuration.ClientSettingsSection, System, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" requirePermission="false" />
    </sectionGroup>
    </configSections>
      <applicationSettings>
        <SnipetTester.Properties.Settings>
          <setting name="SettingSomething" serializeAs="String">
            <value>1234</value>
          </setting>
        </SnipetTester.Properties.Settings>
      </applicationSettings>
    </configuration>

Im Code kann ich folgendermaßen auf die Einstellungen zugreifen:

Console.WriteLine("Default setting value:  " + Properties.Settings.Default.SettingSomething);

Die Idee ist, dass ich, wenn die Anwendung ausgeführt wird, in der Lage sein sollte, zur Laufzeit eine Konfigurationsdatei anzugeben und die Anwendung die Konfigurationsdatei in die Datei laden zu lassenProperties.Settings.Default Objekt, anstatt die Standardeinstellung zu verwendenapp.config Datei. Die Formate der Konfigurationsdateien wären gleich, aber die Werte der Einstellungen wären unterschiedlich.

Ich kenne einen Weg, dies mit dem zu tunConfigurationManager.OpenExeConfiguration(configFile);. In den Tests, die ich ausgeführt habe, wird das jedoch nicht aktualisiertProperties.Settings.Default Objekt, um die neuen Werte aus der Konfigurationsdatei widerzuspiegeln.

Nachdem ich ein bisschen länger darüber nachgedacht habe, konnte ich eine Lösung finden, die mir etwas besser gefällt. Ich bin mir sicher, dass es einige Fallstricke gibt, aber ich denke, es wird funktionieren, wozu ich es brauche.

Im Wesentlichen dieProperties.Settings Klasse wird automatisch von Visual Studio generiert; Es generiert den Code für die Klasse für Sie. Ich konnte herausfinden, wo der Code generiert wurde, und ein paar Funktionsaufrufe hinzufügen, um eine Konfigurationsdatei selbst zu laden. Hier ist mein Zusatz:

internal sealed partial class Settings : global::System.Configuration.ApplicationSettingsBase 
{
    //Parses a config file and loads its settings
    public void Load(string filename)
    {
        System.Xml.Linq.XElement xml = null;
        try
        {
            string text = System.IO.File.ReadAllText(filename);
            xml = System.Xml.Linq.XElement.Parse(text);
        }
        catch
        {
            //Pokemon catch statement (gotta catch 'em all)

            //If some exception occurs while loading the file,
            //assume either the file was unable to be read or
            //the config file is not in the right format.
            //The xml variable will be null and none of the
            //settings will be loaded.
        }

        if(xml != null)
        {
            foreach(System.Xml.Linq.XElement currentElement in xml.Elements())
            {
                switch (currentElement.Name.LocalName)
                {
                    case "userSettings":
                    case "applicationSettings":
                        foreach (System.Xml.Linq.XElement settingNamespace in currentElement.Elements())
                        {
                            if (settingNamespace.Name.LocalName == "SnipetTester.Properties.Settings")
                            {
                                foreach (System.Xml.Linq.XElement setting in settingNamespace.Elements())
                                {
                                    LoadSetting(setting);
                                }
                            }
                        }
                        break;
                    default:
                        break;
                }
            }
        }
    }

    //Loads a setting based on it's xml representation in the config file
    private void LoadSetting(System.Xml.Linq.XElement setting)
    {
        string name = null, type = null, value = null;

        if (setting.Name.LocalName == "setting")
        {
            System.Xml.Linq.XAttribute xName = setting.Attribute("name");
            if (xName != null)
            {
                name = xName.Value;
            }

            System.Xml.Linq.XAttribute xSerialize = setting.Attribute("serializeAs");
            if (xSerialize != null)
            {
                type = xSerialize.Value;
            }

            System.Xml.Linq.XElement xValue = setting.Element("value");
            if (xValue != null)
            {
                value = xValue.Value;
            }
        }


        if (string.IsNullOrEmpty(name) == false &&
            string.IsNullOrEmpty(type) == false &&
            string.IsNullOrEmpty(value) == false)
        {
            switch (name)
            {
                //One of the pitfalls is that everytime you add a new
                //setting to the config file, you will need to add another
                //case to the switch statement.
                case "SettingSomething":
                    this[name] = value;
                    break;
                default:
                    break;
            }
        }
    }
}

Der Code, den ich hinzugefügt habe, enthüllt einProperties.Settings.Load(string filename) Funktion. Die Funktion akzeptiert einen Konfigurationsdateinamen als Parameter. Es analysiert die Datei und lädt alle Einstellungen, auf die es stößt, in die Konfigurationsdatei. Um zur ursprünglichen Konfiguration zurückzukehren, rufen Sie einfach anProperties.Settings.Reload().

Hoffe das könnte jemand anderem helfen!

Antworten auf die Frage(3)

Ihre Antwort auf die Frage