Carregando propriedades. Configurações de um arquivo diferente em tempo de execução

Existe alguma maneira de carregar as configurações de um arquivo diferente do padrãoApp.config arquivo em tempo de execução? Eu gostaria de fazer isso depois que o arquivo de configuração padrão for carregado.

Eu uso oSettings.Settings GUI no Visual Studio para criar meuApp.config arquivo para mim. O arquivo de configuração acaba ficando assim:

    <?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>

No código, consigo acessar as configurações assim:

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

A idéia é que, quando o aplicativo for executado, eu possa especificar um arquivo de configuração no tempo de execução e fazer com que o aplicativo carregue o arquivo de configuraçãoProperties.Settings.Default objeto em vez de usar o padrãoapp.config Arquivo. Os formatos dos arquivos de configuração seriam os mesmos, mas os valores das configurações seriam diferentes.

Eu sei de uma maneira de fazer isso com oConfigurationManager.OpenExeConfiguration(configFile);. No entanto, nos testes que eu executei, ele não atualizaProperties.Settings.Default objeto para refletir os novos valores do arquivo de configuração.

Depois de pensar um pouco mais sobre isso, consegui encontrar uma solução que eu goste um pouco melhor. Tenho certeza que tem algumas armadilhas, mas acho que vai funcionar para o que eu preciso fazer.

Essencialmente, oProperties.Settings classe é gerada automaticamente pelo Visual Studio; Ele gera o código para a classe para você. Consegui encontrar onde o código foi gerado e adicionar algumas chamadas de função para carregar um arquivo de configuração sozinho. Aqui está minha adição:

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;
            }
        }
    }
}

O código que eu adicionei expõe umProperties.Settings.Load(string filename) função. A função aceita um nome de arquivo de configuração como um parâmetro. Ele analisará o arquivo e carregará todas as configurações encontradas no arquivo de configuração. Para voltar à configuração original, basta ligarProperties.Settings.Reload().

Espero que isso possa ajudar alguém!

questionAnswers(3)

yourAnswerToTheQuestion