disasterkid
disasterkid

Reputation: 7278

Use multiple setting files and select them at run time

As of today, I have an App.config file in my project.

I use my config settings in the program like this:

ConfigurationManager.AppSettings["FileDir"];

Where FileDir is a setting in App.config defined like this:

<appSettings>
  <add key="FileDir" value="C:\MyFolder" />
</appSettings>

In my build folder (be it Debug or Release) the file will show up as MyProject.exe.config if my project is named MyProject.

I'd like to add multiple similar config files with the exact same variables but different values and I'd like to point to the config file using command line arguments so that I can reuse the same program but with different settings.

How can I tell my program which config file to choose?

Upvotes: 0

Views: 1090

Answers (3)

RooiWillie
RooiWillie

Reputation: 2228

How about a different solution, especially after stating:

As of today, I have an App.config file in my project.

Why do you not have your own settings class? You could maintain it with a default set of settings in code - something that is much cleaner than trying to maintain several App.config files. Something like:

[Serializable]
public class AppSettings
{
  public string FileDir { get; set; }

  public AppSettings()
  {
    FileDir = string.Empty;
  }

  public AppSettings(string fDir)
  {
    FileDir = fDir;
  }

  public void SetDefault()
  {
    FileDir = "SomeDefault";
  }
}

You could have different instances, or depending on what you need to do, you could load the second set of settings:

m_dSettings = SettingsIO.GetSettings(Path.Combine(Application.StartupPath, "DefaultSettings.xml"));
m_cSettings = SettingsIO.GetSettings(Path.Combine(Application.StartupPath, "CustomSettings.xml"));
m_eSettings = new AppSettings("F:\\Dir");

SettingsIO.WriteSettings(m_dSettings, Path.Combine(Application.StartupPath, "DefaultSettings.xml"));
SettingsIO.WriteSettings(m_dSettings, Path.Combine(Application.StartupPath, "CustomSettings.xml"));
SettingsIO.WriteSettings(m_eSettings, Path.Combine(Application.StartupPath, "ExtraSettings.xml"));

The class to persist the above:

using System.Xml.Serialization;
using System.IO;

public static class SettingsIO
{
  public static void WriteSettings(AppSettings settings, string settingsFilePath)
  {
    XmlSerializer serializer = new XmlSerializer(typeof(AppSettings));

    if (!Directory.Exists(Path.GetDirectoryName(settingsFilePath)))
      Directory.CreateDirectory(Path.GetDirectoryName(settingsFilePath));

    using (StreamWriter SW = new StreamWriter(settingsFilePath))
      serializer.Serialize(SW, settings);
  }

  public static AppSettings GetSettings(string settingsFilePath)
  {
    AppSettings m_Settings = null;

    if (File.Exists(settingsFilePath))
    {
      XmlSerializer serializer = new XmlSerializer(typeof(AppSettings));

      using (FileStream FS = new FileStream(settingsFilePath, FileMode.Open, FileAccess.Read, FileShare.ReadWrite))
        using (StreamReader SR = new StreamReader(FS))
          m_Settings = (AppSettings)serializer.Deserialize(SR);
    }

    if (m_Settings == null)
      m_Settings = new AppSettings();

    return m_Settings;
  }
}

Upvotes: 0

Marco Salerno
Marco Salerno

Reputation: 5203

I would do something like this:

<appSettings>
    <add key="WordV1" value="abc" />
    <add key="WordV2" value="def" />
    <add key="WordV3" value="ghi" />
</appSettings>

string word = ConfigurationManager.AppSettings["WordV" + user.version];

Upvotes: 1

GPW
GPW

Reputation: 2626

Normal approach would be to have transform files which are applied based on the build config. So you still only have one config file but it gets built differently depending on the intended use of the build.

something like SlowCheetah does this, or if you're using something like octopus deploy for deployments then that could do it at deployment time.

https://marketplace.visualstudio.com/items?itemName=VisualStudioProductTeam.SlowCheetah-XMLTransforms

Upvotes: 0

Related Questions