Settings (C#)

Application settings (.NET 2.0 and higher)

Inleiding

Application settings zijn de nieuwe implementatie in .NET 2.0 (VS2005) van Dynamic Properties.
Zij worden bijgehouden in de secties userSettings en applicationSettings van app.config (voor connection strings: connectionStrings).
ApplicationSettings kunnen niet aangepast worden, userSettings wel (maar moeten wel expliciet opgeslagen worden).

Je hoeft ze niet meer zelf in te geven in app.config, er is een interface in Visual Studio om de ingave gemakkelijker te maken.
Properties – Settings.settings (of: dubbelklik op properties en kies links Settings)
VS 2008+: het is beter om de grafische interface te gebruiken, zeker voor stringcollections, anders durft het wel eens mis te lopen.

Voordelen: eenvoudige ingave, typed, maken gebruik van IntelliSense

Code

There're two ways to retrieve application settings in .NET 2.0 or above. One way is to use the AppNamespace.Properties.Settings class which is the recommended way to retrieve application settings. Visual Studio creates a Settings class derived from the ApplicationSettingsBase class for each .settings file in the project. The other way is to use the ConfigurationManager and the Configuration class to retrieve application settings.

Option 1:
// using the Settings class
string test = Properties.Settings.Default.(userSetting/applicationSetting);

Option 2:
// using the ConfigurationManager and the Config class
Configuration config = ConfigurationManager.OpenExeConfiguration(ConfigurationUserLevel.None);
string conn= config.ConnectionStrings.ConnectionStrings["HEPS.Properties.Settings.cmConn"].ConnectionString;
-or-
// ConfigurationManager class provides a shortcut static property to access the connection strings directly
string conn = ConfigurationManager.ConnectionStrings["HEPS.Properties.Settings.cmConn"].ConnectionString;

Saving connectionstring/applicationsettings

Using the ConfigurationManager:
Configuration config = ConfigurationManager.OpenExeConfiguration(ConfigurationUserLevel.None);
config.ConnectionStrings.ConnectionStrings["HEPS.Properties.Settings.cmConn"].ConnectionString = "new connection string";
config.Save();

Code - read StringCollection

System.Collections.Specialized.StringCollection templates = Properties.Settings.Default.Templates;
for (int count = 0; count < templates.Count; count++)
{
xx = templates[count];
}

Really removing Settings in DLL (during development)

Remove the files \Properties\Settings.Settings and Settings.Designer.cs
In x.csproj remove the Itemgroups with this files in.

Having the user changing Settings

This can easily be done with the PropertyGrid. Just set the SelectedObject property to the settings.
propertyGridSettings.SelectedObject = Properties.Settings.Default;

This works for applicationSettings as well as for userSettings.
Mind that only the userSettings can be edited!

Create custom settings

https://www.codeproject.com/Articles/29130/Windows-Forms-Creating-and-Persisting-Custom-User

Add own sections to the config file

Config file

<configSections>
  <!-- Extra custom configuration sections -->
  <section name="FileLocations" type="System.Configuration.DictionarySectionHandler" />
</configSections>

<FileLocations>
  <add key="EUR" value="c:\Floorplan\In_EUR\" />
  <add key="GBP" value="c:\Floorplan\In_GBP\" />
  <add key="PLN" value="c:\Floorplan\In_PLN\" />
</FileLocations>

Code

Dim dicCurrency As IDictionary
dicCurrency = DirectCast(System.Configuration.ConfigurationManager.GetSection("PathSpoolerFiles"), IDictionary)

Used file for the settings

Windows application

The app.config file will be renamed to <Assembly name>.exe.config.
The settings in this file will be used.
If a setting is missing, or the file is missing, the default setting that was in the app.conf file will be used.

Application settings in DLL's

The app.config file will be renamed to <Assembly name>.dll.config.
But by default, the settings in this file will NOT be used.
.NET will search for the settings in the calling assembly.

Common explanation
Reading all settings
http://okapii.com/blog/2010/07/13/changing-dll-settings-without-re-compiling/
http://stackoverflow.com/questions/1208793/reading-dll-config-not-app-config-from-a-plugin-module
Very good: http://stackoverflow.com/questions/594298/c-sharp-dll-config-file

    private Configuration _config;

    /// <summary>
    /// Initializes a new instance of the <see cref="Settings"/> class.
    /// </summary>
    public Settings()
    {
      this.OpenAndStoreConfiguration();
    }

    /// <summary>
    /// Opens the dll.config file and reads its sections into a private List of ConfigurationElement.
    /// </summary>
    private void OpenAndStoreConfiguration()
    {
      string codebase = System.Reflection.Assembly.GetExecutingAssembly().CodeBase;
      Uri p = new Uri(codebase);
      string localPath = p.LocalPath;
      string configName = localPath + ".config";
      ExeConfigurationFileMap fileMap = new ExeConfigurationFileMap();
      fileMap.ExeConfigFilename = configName;
      _config = ConfigurationManager.OpenMappedExeConfiguration(fileMap, ConfigurationUserLevel.None);
    }

    /// <summary>
    /// Gets or sets the <see cref="System.Object"/> with the specified property name.
    /// </summary>
    /// <value></value>
    public override object this[string propertyName]
    {
      get
      {
        string codebase = System.Reflection.Assembly.GetExecutingAssembly().CodeBase;
        Uri p = new Uri(codebase);
        string localPath = p.LocalPath;
        string executingFilename = System.IO.Path.GetFileNameWithoutExtension(localPath);
        string sectionGroupName = "applicationSettings";
        string sectionName = executingFilename + ".Properties.Settings";

        var sectionGroup = _config.GetSectionGroup(sectionGroupName);
        List<ConfigurationElement> settings = ((ClientSettingsSection)sectionGroup.Sections[sectionName]).Settings.OfType<ConfigurationElement>().ToList();
        var result = (from setting in settings
                      where Convert.ToString(setting.ElementInformation.Properties["name"].Value) == propertyName
                      select setting).FirstOrDefault();
        if (result != null)
        {
          return ((SettingValueElement)result.ElementInformation.Properties["value"].Value).ValueXml.InnerText;
        }
        else
        {
          var sections = _config.Sections.OfType<ConfigurationSection>();
          var connSection = (from section in sections
                             where section.GetType() == typeof(ConnectionStringsSection)
                             select section).FirstOrDefault() as ConnectionStringsSection;
          if (connSection != null)
          {
            foreach (ConfigurationElement conn in connSection.ConnectionStrings)
            {
              if (conn.ElementInformation.Properties["name"].Value.ToString() == sectionName + "." + propertyName)
              {
                return conn.ElementInformation.Properties["connectionString"].Value;
              }
            }
          }
        }
        return null;
      }
      // ignore
      set
      {
        base[propertyName] = value;
      }
    }

Manually open a config file

Configuration GetDllConguration()
{
  var configfile = Assembly.GetExecutingAssembly().Location + ".config";
  var map = new ExeConfigurationFileMap { ExeConfigFilename = configfile };
  return ConfigurationManager.OpenMappedExeConfiguration(map, ConfigurationUserLevel.None);
}
ExeConfigurationFileMap configMap = new ExeConfigurationFileMap();
configMap.ExeConfigFilename = @"d:\test\justAConfigFile.config.whateverYouLikeExtension";
Configuration config = ConfigurationManager.OpenMappedExeConfiguration(configMap, ConfigurationUserLevel.None);

Change the default config file

AppDomain.CurrentDomain.SetData("APP_CONFIG_FILE", "c:/test.config");

Web.config transformations

Right click on the web.config. Select 'Add Config Transform'.
The config files that are default generated are: web.Debug.config and web.Release.config.
If you want to change this, you have to Add/Remove/Change project configurations of the project to publish. A config file will be generated for every project configuration.
Personally, I leave Debug and Release for the projects that are not published.
For the project to publish, I leave Debug, I rename Release to Dev and I add Cert and Prod.

If you want to use the config files in combination with a publish method, you also have to add Solution configurations.
Personally I leave Debug, I create Dev, Cert and Prod based on Release and then I remove Release.

Dynamic properties (.NET 1.0)

Inleiding

Dynamic properties worden in .NET 1.0 gebruikt om settings bij te houden.
Zij worden bijgehouden in de sectie appSettings van app.config.
App.config wordt bij de deployment hernoemd naar (naam project).exe.config.

Layout app.config

<?xml version="1.0" encoding="utf-8" ?">
<configuration">
<appSettings">
<add key="Keyname" value="C:\Floorplan\Out\"/">
</appSettings">
</configuration">

Code

Using System.Configuration;
strValue[] = ConfigurationManager.AppSettings.GetValues("AuthorizationProvider");
eenvoudiger: strValue = ConfigurationManager.AppSettings.GetValues("AuthorizationProvider")[0];
of: strValue = ConfigurationManager.AppSettings["AuthorizationProvider"];
Obsolete (VB2003): ConfigurationSettings.AppSettings.GetValues("AuthorizationProvider")

Gebruik eigen secties

De sectie wordt hierbij in een object geladen, bijvoorbeeld een dictionary. Je werkt dan verder met deze dictionary.
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<configSections>
<section name="PathSpoolerFiles" type="System.Configuration.DictionarySectionHandler" />
</configSections>
<appSettings>
<add key="OutFilePath" value="C:\Floorplan\Out\"/>
</appSettings>
<PathSpoolerFiles>
<add key="EUR" value="C:\Floorplan\In_EUR\" />
<add key="GBP" value="C:\Floorplan\In_GBP\" />
<add key="PLN" value="C:\Floorplan\In_PLN\" />
</PathSpoolerFiles>
</configuration>

Referentie

Unless otherwise stated, the content of this page is licensed under Creative Commons Attribution-ShareAlike 3.0 License