Read/Write App.config with .NET 2.0/Enterprise Library

This time I would like to show you the most important changes in the System.Configuration namespace with .NET 2.0.
I have looked at my blog referrer statistics and saw about 20 hits/day by Google. Most of them were searching 
infos how to configure the new Enterprise Library but also a significant number of people which seem to seek guidance to the
following questions:
  • How to read/write to App.Config?
  • How to store a list of objects in a config file via the System.Configuration mechanism?
Reason enough for me to shed more light on the System.Configuration namespace.
The main changes from .NET 1.0/1.1 in the System.Configuration namespace are:
  • Write to your App.Config file through the Configuration class.
  • New configuration model for Windows Forms applications.
  • Store complex objects including object collections in your App.Config File.
  • It is possible to store Connection Strings in the App.Config file see ConnectionSettings this enables you to store you settings on a SQL Server. The Enterprise Library for Sample SqlConfiguration exercises this by implementing a SqlConfigurationSource which can store and retrieve a ConfigurationSection.
So where to start? I think I show you at first the config file and explain how you can create it programtically in your application.

The easiest way to read/write AppSettings

If you want to store only key/value pairs in your App.config file there is a special section in reserved which allows you to do exactly that. Simply add an <appsettings> section and add your data as key/value pairs of the form <add key="xxx" value="xxxx" />. Thats all to create new app.config file with settings in it.

App.Config
<? xml version = "1.0"encoding="utf-8" ?>
< configuration >
 < appSettings >
    < add key = "Setting1"value="Very" />
    < add key = "Setting2"value="Easy" />
  </ appSettings >
</ configuration >

The data access API has been changed for this type of setting with .NET 2.0. The "old" one liner ConfigurationSettings.AppSettings  has been deprecated in favor of ConfigurationManager.AppSettings. Beside from the naming change you can now also write your application settings. For read only access you can look at the ShowConfig function defined below. Writing the last modification time is demonstrated in the Main function.

using System;
using System.Collections.Generic;
using System.Text;
using System.Configuration;
 
namespace AppSettings
{
    class Program
    {
        static void ShowConfig()
        {
            // For read access you do not need to call the OpenExeConfiguraton
            foreach (string key in ConfigurationManager.AppSettings)
            {
                string value = ConfigurationManager.AppSettings[key];
                Console.WriteLine("Key: {0}, Value: {1}", key, value);
            }
        }
 
        static void Main(string[] args)
        {
            ShowConfig();
 
            // Open App.Config of executable
            System.Configuration.Configuration config =
              ConfigurationManager.OpenExeConfiguration(ConfigurationUserLevel.None);
 
            // Add an Application Setting.
            config.AppSettings.Settings.Add("Modification Date",
              DateTime.Now.ToLongTimeString() + " ");
 
            // Save the configuration file.
            config.Save(ConfigurationSaveMode.Modified);
 
            // Force a reload of a changed section.
            ConfigurationManager .RefreshSection("appSettings");
 
            ShowConfig();
 
        }
    }
}
Expected Output:
Key: Settings1, Value: Very
Key: Setting2, Value: Easy
Key: Settings1, Value: Very
Key: Setting2, Value: Easy
Key: Modification Date, Value: 01:21:03

With this mechanism you can read and update simple key/value pairs within your application without digging any deeper in the System.Configuration namespace. The following examples show the other features like the new windows forms configuration mechanism, create your own configuration section and how you can easily store lists of objects in the App.config file with the new Enterprise Library helper classes.

Windows Forms Configuration
When developing Windows Forms with VS2005 you get for free a new configuration mechansim. They Forms designers were so nice to create from your config values automatically an access class and came up with an consistent model to store application global config files in the app.config.exe file and user specific settings within the user profile in user.config.
Please note that the Forms configuration model is not available in class library projects since you have no App.config file for your Dll. When you add a settings file to your class library project you can and merge the settings with the App.config  file of your hosting executable. This can be useful if you want to enforce that every application that uses your library can have its own settings inside the App.config file of the executable. You have the freedom to store your settings where ever you would like to. Any provider can be plugged into your config data access class by decorating your configuration class with the  SettingsProviderAttribute. If none is specified the  LocalFileSettingsProvider  is used which relies on the System.Configuration. This is the reason why you do not need to reference the System.Configuration assembly in a windows forms but you see the System.Configuration assembly loaded in your windows forms application. You can check it with the debugger in the loaded modules list.
Below is a new Windows Forms project shown  which was generated via New->Project->Windows Application. The new configuration features are visible in the Properties folder of your project. There go your resources and the automatically generated strongly typed resource access class with static properties to allow easy and type safe access to your resources. This is similar to the old C programming model with windows resources. You had an header file with resource ids generated by the resource compiler which spits out an header file which is compiled (compile time checking of the existence of resources) and an object file which is linked into you target. Now you have also compile time checking in .NET if you access your resources via the static properties.
The configuration features surface in the auto generated Settings.settings file and Settings.Designer.cs. 
To create new configuration values you have full Designer integration within Visual Studio (see picture below) . In your code you can read /modify these settings via the generated access class. Inside the visual editor you can choose between two scopes for each of your configuration settings: Application and User. The Application scope defines configuration values which cannot be changed by the user and are the same for all users of this application. User scoped settings on the other hand can be changed/created by, well the users and are stored within their local profile. Addendum: Application scoped settings cannot be altered when you save your settings. Only the user settings are written to disk during a save operation!


VS 2005 generated Windows Forms application skeleton.

User Specifc Application Settings


Settings.settings 
(Generated by Visual Studio)
                <? xml version = '1.0'encoding='utf-8'?>
                < SettingsFile xmlns = "http://schemas.microsoft.com/VisualStudio/2004/01/settings"CurrentProfile="(Default)"GeneratedClassNamespace="WindowsApplication1.Properties"GeneratedClassName="Settings">
                  < Profiles />
                  < Settings >
                    < Setting Name = "testSetting"Type="System.String"Scope="User">
                      < Value Profile = "(Default)">Form1</Value>
                    </ Setting >
                  </ Settings >
                </ SettingsFile >



Settings.Designer.cs (Generated by Visual Studio using the SettingsSingleFileGenerator as Custom Build Tool)

    namespace WindowsApplication1.Properties 
    {
       internal sealed partial class Settings : global::System.Configuration.ApplicationSettingsBase 
       {
       
          private static Settings defaultInstance = 
            ((Settings)(global::System.Configuration.ApplicationSettingsBase.Synchronized(new Settings())));
       
          public static Settings Default 
          {
            get 
            {
                return defaultInstance;
            }
          }
       
          [global::System.Configuration.UserScopedSettingAttribute()]
          [global::System.Configuration.DefaultSettingValueAttribute("Form1")]
          public string testSetting 
          {
             get 
             {
                 return ((string)(this["testSetting"]));
              }
             set 
             {
                 this["testSetting"] = value;
             }
          }
      }
    }

 

To load your settings programtically you only need to to  do a

            Settings set = Settings.Default;

and access your settings via the property of the returned instance.
            string str = set.testSetting;
Wow that was easy. Wasn´t it? Now lets save our changed test setting:
            set.testSetting = "test value";
            set.Save();
That's pretty much it. To display some of your settings in your form you can use data binding and let your users configure the application font, color, .... User specific settings are stored in  %APPDATA%/<AppName>/<AppName><AppConfigName_GUID>/<AssemblyVersion>/user.config. The path to the user config is on my machine is e.g. %APPDATA%/ WindowsApplication1/WindowsApplication1.exe_Url_x00ebzylso3e0rtwd1pnxkhduwr34pgb/1.0.0.0. This enables you to install a Windows Forms App as Administrator for all users with some global settings in the executable App.config and user specific settings which are stored in the user profile. If your users are in a domain with a roaming profile they will get the same profile and thus the same user settings on every computer they work.

Is this new mechanism compatible with the old one?

Yes it is. Even more: These nice classes do rely heavily on the System.Configuration features. Each user/application section is put into its own ConfigurationSectionGroupCollection which can be accessed programtically. Every group does contain one or more configuration section/s of the type ClientSettingsSection which does serve as container for your strongly typed key/value pairs. The following code does enumerate all your auto generated settings and does print them out to the Console.


            // Get the application configuration file.
            System.Configuration.Configuration config =
                    ConfigurationManager.OpenExeConfiguration(
                    ConfigurationUserLevel.None);
 
            // Get the collection of the section groups.
            ConfigurationSectionGroupCollection sectionGroups = config.SectionGroups;
            // Show the configuration values
            ShowSectionGroupCollectionInfo(sectionGroups);
 
        static void ShowSectionGroupCollectionInfo(ConfigurationSectionGroupCollection sectionGroups)
        {
            ClientSettingsSection clientSection;
            SettingValueElement value;
 
            foreach (ConfigurationSectionGroup group in sectionGroups)  // Loop over all groups
            {
                if (!group.IsDeclared) // Only the ones which are actually defined in app.config
                    continue;
 
                Console.WriteLine("Group {0}", group.Name);
 
                foreach (ConfigurationSection section in group.Sections) // get all sections inside group
                {
                    clientSection = section as ClientSettingsSection;
                    Console.WriteLine("/tSection: {0}", section);
                    if (clientSection == null)
                        continue;
 
                    foreach (SettingElement set in clientSection.Settings)
                    {
                        value = set.Value as SettingValueElement;
 
                        // print out value of each section
                        Console.WriteLine("/t/t{0}: {1}",set.Name,value.ValueXml.InnerText);
                    }
                }
            }
        }

How To Read/Write Another App.Config File
To open another App.Config file you need to create an instance of ExeConfigurationFileMap. The purpose of this class is not that obvious but we can use it to open another file. Once you have learned this little trick the rest is easy. Here is a little example that does open an file by specifying it's name.

            ExeConfigurationFileMap fileMap = new ExeConfigurationFileMap();
            fileMap.ExeConfigFilename = @"ConfigTest.exe.config";  // relative path names possible
            // Open another config file
            Configuration config = ConfigurationManager.OpenMappedExeConfiguration(fileMap, ConfigurationUserLevel.None);
 
            // read/write from it as usual
            ConfigurationSection mySection = config.GetSection("mySection");
            config.SectionGroups.Clear(); // make changes to it
            config.Save(ConfigurationSaveMode.Full);  // Save changes

The Microsoft Enterprise Library way has a shorthand utility class for this. It is the FileConfigurationSource which does hide those strange things. Tom Hollander has a nice post explaining this already so I will not repeat the same at my blog.

Another Way to read/write configuration values

A more advanced way to store our settings is to create our own ConfigurationSection. This makes our configuration values distinguishable from other configuration values inside the App.config file. It is a little more complicated since you have to write your own class which content is de/serialized to the App.config file. I am going to show you at first the config file and explain then what code you need to write to read/save these settings to your application configuration file.

App.Config  (Taken from the Enterprise Library Configuration Migration QuickStart Sample)
< configuration >
 < configSections >
    < section name = "EditorSettings"type="ConfigurationMigrationQuickStart.EditorFontData, ConfigurationMigrationQuickStart, Version=1.1.0.0, Culture=neutral, PublicKeyToken=null" />
 </ configSections >
 < EditorSettings name = "Verdana"size="24"style="2" />
</ configuration >
Most App.config files which contain config data have a  < configSections element where many  < section > are defined. The  name attribute of an section (in this example "EditorSettings") tells the config system that the class  ConfigurationMigrationQuickStart.EditorFontData is responsible for the ser/deserialization of the node  < EditorSettings >. The EditorFontData class derives from the ConfigurationSection class and uses the ConfigurationProperty attribute to create a mapping between the properties to de/serialize and the attribute names in names in the App.Config file.

      using System.Text;
      using System.Configuration; 
      public class EditorFontData : ConfigurationSection
      {          
 
            public EditorFontData()
            {         
            }
 
            [ConfigurationProperty("name")]
            public string Name
            {
                  get { return (string)this["name"]; }
                  set{ this["name"] = value; }
            }
 
            [ConfigurationProperty("size")]
            public float Size
            {
                  get{ return (float)this["size"]; }
                  set{ this["size"] = value; }
            }
 
            [ConfigurationProperty("style")]
            public int Style
            {
                  get { return (int)this["style"]; }
                  set { this["style"] = value; }
            }
      }
To access an EditorFontData instance with values from your config file you only need to call

   EditorFontData configData = ConfigurationManager.GetSection("EditorSettings") as EditorFontData;
Please note that the System.Configuration.ConfigurationManager returns only objects with read only properties. Subsequent calls to GetSection use the cached instance inside the ConfigurationManager. This constraint requires you to create every time a new instance of you e.g. EditorFontData object if you want to write to the App.config file. You even cannot add an object with the same name twice to the System.Configuration.Configuration object. Now comes the fun part: To edit an existing App.config file you have to remove your config object and then add a new object instance to the Configuration object. Only then the Save will succeed.

                EditorFontData configData = new EditorFontData();
                configData.Name = "Arial";
                configData.Size = 20;
                configData.Style = 2;
               
                // Write the new configuration data to the XML file
                Configuration config = ConfigurationManager.OpenExeConfiguration(ConfigurationUserLevel.None);
                config.Sections.Remove("EditorSettings");
                config.Sections.Add("EditorSettings", configData);
                config.Save();

To get your hands on the System.Configuration.Configuration object you have to open your App.Config file. The .NET config mechanism supports setting inheritance from the Machine.config from which all settings are inherited. Next comes the App.Config file which is selected by the ConfigurationUserLevel.None file.



Enterprise Library Configuration Helpers

The Enterprise Library for .NET 2.0 has made it a lot easier to use the System.Configuration classes.More info how to configure the new application blocks you can  be found in another article. Lets suppose you want to store a collection of strongly typed named objects in our App.Config file. In this example it is a plugin configuration file where a list of plugins can be added and the selected plugin be started. The config file could look like this:

<? xml version = "1.0"encoding="utf-8" ?>
< configuration >
 < configSections >
    < section name = "PluginConfiguration"type="EntlibInjection.PluginManagerConfiguration, EntlibInjection, Version=2.0.0.0, Culture=neutral, PublicKeyToken=null" />
 </ configSections >
 
 < PluginConfiguration name = "Configured Plugins"SelectedPlugin="2D">
    < Plugins >
      <!-- type="EntlibInjection.PluginData, EntlibInjection, Version=2.0.0.0, Culture=neutral, PublicKeyToken=null" -->
      < add name = "2D" cfgfile = "2D.config" plugintype="EntlibInjection.TwoD, EntlibInjection, Version=2.0.0.0, Culture=neutral, PublicKeyToken=null"type=""/>
      < add name = "3D"plugintype="ThreeDPlugin.ThreeD, ThreeDPlugin, Version=2.0.0.0, Culture=neutral, PublicKeyToken=null"type=""/>
    </ Plugins >
 </ PluginConfiguration >
 
</ configuration >

We want a PluginConfiguration class which selects a plugin and contains a list of plugins. To make it work we first need to define the PluginManagerConfiguration class. We need the Enterprise Library  only for the  IConfigurationSource interface to load our config from other files than App.config or even an SQL server.

PluginManagerConfiguration.cs

using System;
using System.Configuration;
using System.ComponentModel;
using System.Collections.Generic;
using System.Text;
using Microsoft.Practices.EnterpriseLibrary.Common.Configuration;
 
namespace EntlibInjection
{
    public class PluginManagerConfiguration : SerializableConfigurationSection
    {
            private const string selectedPlugin = "SelectedPlugin";
            private const string PluginCollectionProperty = "Plugins";
            private const string nameProperty = "name";
 
 
            ///<summary>
            /// Configuration section name for Plugin Configuration
            ///</summary>
            public const string SectionName = "PluginConfiguration";
 
 
            public PluginManagerConfiguration()
            {
 
            }
 
            ///<summary>
            /// Gets the configured plugin settings section in the configuration source.
            ///</summary>
            ///<param name="configurationSource">The <see cref="IConfigurationSource"/> to get the section from.</param>
            ///<returns>The plugin configuration.</returns>
           public static PluginManagerConfiguration GetPluginSettings(IConfigurationSource configurationSource)
            {
               return (PluginManagerConfiguration)configurationSource.GetSection(PluginManagerConfiguration.SectionName);
            }
 
            ///<summary>
            /// Get/Set the selected plugin
            ///</summary>
           [ConfigurationProperty(selectedPlugin, IsRequired = true)]
            public string SelectedPlugin
            {
                  get
                  {
                     return (string)this[selectedPlugin];
                  }
                  set
                  {
                     this[selectedPlugin] = value;
                  }
            }
 
        ///<summary>
        /// Name of the configuration node.
        ///</summary>
        [ConfigurationProperty(nameProperty)]
        [EditorBrowsable(EditorBrowsableState.Never)]
        public string Name
        {
            get
            {
                return (string)this[nameProperty];
            }
            set
            {
                this[nameProperty] = value;
            }
        }
 
            ///<summary>
            /// This property contains a list of plugins
            ///</summary>
            [ConfigurationProperty(PluginCollectionProperty)]
            public PluginDataCollection Plugins
            {
                  get
                  {
                      return (PluginDataCollection)base[PluginCollectionProperty];
                  }
            }
 
    }
}

After the definition of the Configuration Section we need the collection class which contains a list of elements. If you want a list of strongly typed data elements in the config file you can use the PolymorphicConfigurationElementCollection<T> generic which is introduced by the Enterprise Library. This class was specifically designed to store lists of the following form:
< SectionName >
      < add name = "blah" type=" PluginData strongly typed " xxx="xxxx" xxx="xxxx" .../>
</ SectionName >

You have to derive from PolymorphicConfigurationElementCollection and implement the RetrieveElementConfigurationElementType where you retrieve the data type which is responsible for the ser/deserialization of the other attributes of this node. Error handling code has been omitted. Please have a look at e.g. the Logging Application Block of Entlib to see the correct error handling.
 
PluginDataCollection.cs

using System;
using System.Collections.Generic;
using System.Text;
using System.Xml;
using System.Configuration;
using Microsoft.Practices.EnterpriseLibrary.Common.Configuration;
 
 
namespace EntlibInjection
{
    public class PluginDataCollection : PolymorphicConfigurationElementCollection<PluginData>
    {
            ///<summary>
            /// Returns the <see cref="ConfigurationElement"/> type to created for the current xml node.
            ///</summary>
            ///<remarks>
            /// The <see cref="PluginData"/> include the configuration object type as a serialized attribute.
            ///</remarks>
            ///<param name="reader"></param>
            protected override Type RetrieveConfigurationElementType(XmlReader reader)
            {
                 return typeof(PluginData);
            }
 
    }
}
I have simplified the RetrieveConfigurationElementType a lot compared to the normally used strongly typed name which should be specified to allow versioning of you configuration node data types. Please do NOT use this shortcut in production environments. If you do not want strong names for your data types then the PolymorphicConfigurationElementCollection<xxx> is not the right choice for your problem. Instead a direct derivate of ConfigurationElementCollection is the better alternative for you. Do not ask me how to figure out with which version of PluginData you App.Config was created when you do not use strong names for your data types.This can be an important issue if you plan e.g. to create configuration converters from one version to the next. Please have a look at the Logging Block code e.g. TraceListenerDataCollection how the  PolymorphicConfigurationElementCollection<xxx> is correctly implemented. Ok so much for versioning. Now we can create our PluginData class which contains the plugin data type and an external config file which contains the plugin configuration. If it is not specified we assume the the plugin configuration is located in the App.config file. This can be  implemented by switching from SystemConfigurationSource to FileConfiguratonSource and put the plugin config file into it.
 
using System;
using System.ComponentModel;
using System.Collections.Generic;
using System.Text;
using Microsoft.Practices.EnterpriseLibrary.Common.Configuration;
using System.Configuration;
 
 
namespace EntlibInjection
{
    public class PluginData : NameTypeConfigurationElement
    {
        public const string PluginTypeProperty = "plugintype";
        public const string PluginConfigProperty = "cfgfile";
 
 
          private static IDictionary<string, string> emptyAttributes = new Dictionary<string, string>(0);
 
     
            public PluginData()
            {
            }
 
            protected PluginData(string name, Type PluginType)
                  : base(name, PluginType)
            {
                this.PluginType = this.GetType();
            }
 
 
 
            [ConfigurationProperty(PluginConfigProperty, DefaultValue="", IsRequired = false)]
            public string ConfigFile
            {
                  get
                  {
                     return (string)this[PluginConfigProperty];
                  }
                  set
                  {
                     this[PluginConfigProperty] = value;
                  }
            }
 
 
            [ConfigurationProperty(PluginTypeProperty, IsRequired= true)]
            [TypeConverter(typeof(AssemblyQualifiedTypeNameConverter))]
            public Type PluginType
            {
                  get
                  {
                        return (Type)this[PluginTypeProperty];
                  }
                  set
                  {
                        this[PluginTypeProperty] = value;
                  }
            }
    }
}
 
To load the configuration form a config file you can use the FileConfigurationSource from the Enterprise Library and you are ready to rockn roll.
         FileConfigurationSource configurationSource = new FileConfigurationSource(“2D.config”);
         PluginManagerConfiguration .GetPluginSettings(configurationSource);
There are many new things within the System.Configuration namespace which this article tries to show you how the can be used. I hope this article gives you enough starting points to jump up on the .NET 2.0 wagon and the new Enterprise Library. One last thing: User settings are not supported by the Enterprise Library. But you can fake this by creating a config file in %APPDATA%/MyEntlibApp/<MyEntlibApp Assembly Version>/User.config and load it from there. To make this work you need a loaded user profile which is not always present e.g.  System Service. In this case you need to load some trusted user profile to make it work.

 
Print posted @ Wednesday, January 04, 2006 10:55 PM

Feedback
# re: Read/Write App.config with .NET 2.0/Enterprise Library
What a great post. Most appreciated. 2/1/2006 2:52 PM | Shaun
# re: Read/Write App.config with .NET 2.0/Enterprise Library
Alois,
Very good article.
Is that possible to have elements or collections within a collection element? I happen to have a exising configuration file with nested collections in the collections.
Thanks! 2/5/2006 6:04 PM | Richard Tang
# re: Microsoft Enterprise Library for .NET 2.0: Configuration
2/7/2006 3:23 PM | Alois Kraus
# re: Read/Write App.config with .NET 2.0/Enterprise Library
Best post on this subject to date! 3/1/2006 7:31 AM | Thomas
# re: Read/Write App.config with .NET 2.0/Enterprise Library
Great Post! 3/21/2006 5:22 PM | Draco
# re: Read/Write App.config with .NET 2.0/Enterprise Library
Great article, answered a lot of my questions. One question, I have left is trying to access application settings created in one project from another project. I created ConnectionString var in my start up project, but I need to access the ConnectionString var from another project in the same solution. Doesn't seem like I can do this. If I do it the other way and create the ConnectionString var in the project that I need it for, the ConnectionString var no longer appears in the AppConfig.exe file when I compile my application. Any ideas on how to access app settings from another project?
Thanks 4/4/2006 10:24 PM | SB
# re: Read/Write App.config with .NET 2.0/Enterprise Library
If you mean other project you mean App.Config of another applicaton? It is possible to refer from one section to another App.Config file by using the configSource Attribute. More info can be found at MSDN and Tom Hollander Blog: http://blogs.msdn.com/tomholl/archive/2006/04/02/entlib2externalconfig.aspx

Yours,
Alois Kraus
4/5/2006 8:19 PM | Alois Kraus
# re: Read/Write App.config with .NET 2.0/Enterprise Library
Hello,

How can we do the RefreshSection on app.config that is not the config file of the Start Up Project.

My problem is that I have 3 projects One defined as the Start Up project and the two others are library, and my connectionString is in a library and what I can say is the ConfigurationManager.RefreshSection does not working on it. If you can just explain how we dow the refresh on the library.

Thank you.

Gilles 4/12/2006 12:13 PM | Gilles Prod'Hon
# re: Read/Write App.config with .NET 2.0/Enterprise Library
My problem is: I have several projects within my solution. I create the AppConfig file in my startup project. However, if I try to access any settings in the AppConfig file, for example ConnectionString setting, from any project that is not the startup project I am not able to. It seems the settings are now out of scope. How can I access the settings in the AppConfig file from a project that is not the start up project? Thanks. 4/25/2006 7:17 PM | SB
# How to Read / Write App.config with .NET 2.0 / Enterprise Library
4/26/2006 10:51 AM | Murray Gordon
# re: Read/Write App.config with .NET 2.0/Enterprise Library
Hi,

to open another app.config file on the fly you can do the following:
ExeConfigurationFileMap fileMap = new ExeConfigurationFileMap();
fileMap.ExeConfigFilename = fileName;
System.Configuration.Configuration config = ConfigurationManager.OpenMappedExeConfiguration(fileMap, ConfigurationUserLevel.None);

// Now you can do a
config.GetSection,
Add/RemoveSection
and
config.Save

as you like.

HTH,

Alois Kraus

4/28/2006 9:06 PM | Alois Kraus
# re: Read/Write App.config with .NET 2.0/Enterprise Library
Hi Alois,

I'd searched for a long time information (samples of course!) on the configuration classes in EL 2.0.. all in vain until I found this blog!

Two thumbs up! Sorry I only have two hands!! :-) 5/14/2006 3:39 PM | Jude Wong
# re: Read/Write App.config with .NET 2.0/Enterprise Library
Hi
If I don't know the Database name (for example) until run-time (when the User choses it from a List), how can I ensure that all the various Enterprise Libs, Membership providers get to use the new, correct ConnectionString?

Of course, I can write back to the app.config. But in my case the App runs on Terminal Services, and so I would have a problem with multiple users.

What I would like to do is have a Configuration String Provider, which all Libs use. But it does not seem that System.Configuration.Providers is intended for ths. Am trying to use a Protected Config String provider as all Libs will use the Decrypt method.
Do you have any other suggestions?
Thanks
John
6/2/2006 10:38 AM | John Radley
# re: Read/Write App.config with .NET 2.0/Enterprise Library
Hi John please drop me a mail so I can save some space in my comments section ;-) 6/2/2006 9:40 PM | none
# re: Read/Write App.config with .NET 2.0/Enterprise Library
I'm trying to follow your examples to store config data in separate files (dataconfiguration.config and siteconfiguration.config), but I keep getting "... section 'siteConfiguration' does not exist in ... web.config or machine.config ... Make sure that the 'enterpriseLibrary.configurationSections' configuration section exists in one of the files and that the section 'siteConfiguration' is defined."

Here is what I have so far. Any help is greatly appreciated.


WEB.CONFIG:
<configSections>
<section name="enterpriseLibrary.ConfigurationSource" type="Microsoft.Practices.EnterpriseLibrary.Common.Configuration.ConfigurationSourceSection, Microsoft.Practices.EnterpriseLibrary.Common, Version=2.0.0.0, Culture=neutral, PublicKeyToken=null" />
</configSections>
<enterpriseLibrary.ConfigurationSource selectedSource="System Configuration Source">
<sources>
<add name="dataConfiguration" type="Microsoft.Practices.EnterpriseLibrary.Common.Configuration.FileConfigurationSource, Microsoft.Practices.EnterpriseLibrary.Common, Version=2.0.0.0, Culture=neutral, PublicKeyToken=null" filePath="dataconfiguration.config" />
<add name="siteConfiguration" type="Microsoft.Practices.EnterpriseLibrary.Common.Configuration.FileConfigurationSource, Microsoft.Practices.EnterpriseLibrary.Common, Version=2.0.0.0, Culture=neutral, PublicKeyToken=null" filePath="siteconfiguration.config" />
<add name="System Configuration Source" type="Microsoft.Practices.EnterpriseLibrary.Common.Configuration.SystemConfigurationSource, Microsoft.Practices.EnterpriseLibrary.Common, Version=2.0.0.0, Culture=neutral, PublicKeyToken=null" />
</sources>
</enterpriseLibrary.ConfigurationSource>


DATACONFIGURATION.CONFIG:
<configuration>
<configSections>
<section name="dataConfiguration" type="Microsoft.Practices.EnterpriseLibrary.Data.Configuration.DatabaseSettings, Microsoft.Practices.EnterpriseLibrary.Data, Version=2.0.0.0, Culture=neutral, PublicKeyToken=null" />
</configSections>
<connectionStrings>
<add name="Content" connectionString="..."
providerName="System.Data.SqlClient" />
</connectionStrings>
</configuration>


SITECONFIGURATION.CONFIG
<configuration>
<configSections>
<section name="siteConfiguration" type="com.intraFrame.utilSiteConfiguration, Informatics, Version=1.1.0.0, Culture=neutral, PublicKeyToken=null" />
</configSections>
<siteConfiguration>
<Environment>local</Environment>
<SiteID>83</SiteID>
...
</siteConfiguration>
</configuration>


COMMON.VB
Public Class utilSiteConfiguration
Private _Environment As String
Private _ServerPath As String

Public Property Environment() As String
Get
Return Me._Environment
End Get
Set(ByVal Value As String)
Me._Environment = Value
End Set
End Property

Public Property ServerPath() As String
Get
Return Me._ServerPath
End Get
Set(ByVal Value As String)
Me._ServerPath = Value
End Set
End Property
End Class


PAGE.ASPX.VB
Imports System.Configuration
...
Function configData() As utilSiteConfiguration
Dim getConfig As utilSiteConfiguration = CType(ConfigurationManager.GetSection("siteConfiguration"), utilSiteConfiguration)
Return getConfig
End Function
7/6/2006 5:56 PM | Steve
# re: Read/Write App.config with .NET 2.0/Enterprise Library
Hi Steve,

I have updated my article to answer your question.

Yours,
Alois Kraus
7/6/2006 7:01 PM | Alois Kraus
# Read/Write App.config with .NET 2.0/Enterprise Library
Read/Write App.config with .NET 2.0/Enterprise Library 7/12/2006 9:03 PM | aeraのブログ
# Read/Write App.config with .NET 2.0/Enterprise Library
Read/Write App.config with .NET 2.0/Enterprise Library 7/12/2006 9:15 PM | aeraのブログ
# Donde esta el Application Block de Configuracion en Enterprise Library 2.0 ???
Esta pregunta me la han hecho varias veces, desde el lanzamiento de Enterprise Library 2.0 , y la respuesta 8/16/2006 2:57 AM | ElBruno
# re: Read/Write App.config with .NET 2.0/Enterprise Library
Hi Alois,
I need your help badly.

I'm using .NET 2.0.
I've included "using System.Diagnostics;"
When I try using "ConfigurationManager.AppSettings"
I'm getting following error:
"Error 8 The name 'ConfigurationManager' does not exist in the current context "C:/..../Test.cs".

At the end I took your code and I'm having same problem :-(

I can not find ConfigurationManager in System module via Object Browser.

Any ideas?
Thanks,
Eugene.
8/16/2006 3:00 PM | Eugene
# re: Read/Write App.config with .NET 2.0/Enterprise Library
I am having the same problem as Eugene. I cannot select a ConfigurationManager from anywhere. 8/16/2006 3:29 PM | Chris
# re: Read/Write App.config with .NET 2.0/Enterprise Library
You need to add the system.configuration reference in the project . He should have mentioned this since it is not part of the standard. 8/26/2006 11:11 AM | Lars
# re: Read/Write App.config with .NET 2.0/Enterprise Library
Hi Alois, very good article!

Inspired from it, I'm trying to write a proc that stores user settings in app.exe.config insted user.config. I will use it in substitution of Properties.Settings.Default.Save(). Here the code:

static void SaveUserSettings()
{
ClientSettingsSection clientSection;
SettingValueElement value;

System.Configuration.Configuration config =
ConfigurationManager.OpenExeConfiguration(ConfigurationUserLevel.None);

ConfigurationSectionGroup group = config.SectionGroups["userSettings"];
if (group == null)
throw new InvalidOperationException("Gruppo userSettings non presente nel file di configurazione");

foreach (ConfigurationSection section in group.Sections)
{
clientSection = section as ClientSettingsSection;
ClientSettingsSection newSection = new ClientSettingsSection();

if (clientSection == null)
continue;

foreach (SettingElement set in clientSection.Settings)
{
value = set.Value as SettingValueElement;
value.ValueXml.InnerText = Properties.Settings.Default[set.Name].ToString();
newSection.Settings.Add(set);
}

config.Sections.Remove("userSettings");
config.Sections.Add("userSettings", newSection);
}

config.Save(ConfigurationSaveMode.Full);
}


So far, so good. The proc works properly on strings but, with some types (eg. Font) the string written in the file is in a different format than the original

Setting writed with Properties.Settings.Default.Save():

<setting name="Test" serializeAs="String">
<value>Arial, 11.25pt, style=Bold</value>


Setting writed with my proc:

<setting name="Test" serializeAs="String">
<value>[Font: Name=Arial, Size=11, Units=3, GdiCharSet=1, GdiVerticalFont=False]</value>


...i suppose the problem is in the line:

value.ValueXml.InnerText = Properties.Settings.Default[set.Name].ToString();


Can you help me?!?!
Thanks in advance
Michele 9/21/2006 2:07 PM | MicheleB
# re: Read/Write App.config with .NET 2.0/Enterprise Library
Hi Michele,

this is not so easy since there seems to go some magic in the background going on to find out the correct type do deserialize from

<setting name="s4" serializeAs="String">
<value>Microsoft Sans Serif, 8.25pt</value>
</setting>
I think you will need to do reflection on the accessor class to find for each property name the returned type and with this knowledge the corresponding settings name inside your App.config. It is a bit more work but if you want to save in a generic way this would be the way to go. If this is worth the effort is another question.

Yours,
Alois Kraus

9/23/2006 6:59 AM | Alois Kraus
# ¿Donde esta el Application Block de Configuracion en Enterprise Library 2.0?
Esta pregunta me la han hecho varias veces, desde el lanzamiento de Enterprise Library 2.0 , y la respuesta 9/30/2006 5:01 AM | El Bruno
# How to Read / Write App.config with .NET 2.0

Thanks to Alois Kraus. Great content on reading and writing config files using .NET 2.0

Read/Write... 10/11/2006 5:51 PM | Clayton Firth's Blog
# re: Read/Write App.config with .NET 2.0/Enterprise Library
To update key in AppSetings you need to Remove and then Add key.
I've posted the helper method http://geekswithblogs.net/mnf/archive/2006/11/21/97693.aspx 12/1/2006 3:19 AM | Michael Freidgeim
# re: Read/Write App.config with .NET 2.0/Enterprise Library
Very good post. One thing I'm still wondering about is how to save XML data. I've been saving in an XML file, so all the data is already in an XmlDocument. Surely, if anything, this ought to be easier than de/serialing a binary object into XML and then saving it.

Thanks for any advice. 12/5/2006 2:11 AM | Darrell Plank
# re: Read/Write App.config with .NET 2.0/Enterprise Library
In the previous post, I said, regarding putting an XmlDocumnt into the config file "surely, if anything, this ought to be easier than de/serialing a binary object into XML and then saving it". I've read more and am pretty much concluding that in spite of the fact that this seems to make sense, the reality is the precise opposite - instead of being simple, it's actually impossible to directly place an XmlDocument/XmlNode into the config file.

Which brings up a much larger question for the community at large regarding the design for this configuration stuff. Isn't all of this solely for the purpose of putting some arbitrary XML into app.config? And don't they already have great facilities for producing XML? So why this totally new design to turn a type into XML solely for the configuration file? Why didn't they just give us a simple "SaveXmlToConfigFile(string appName, XmlNode node)"? Wouldn't this single, simple call have replaced all of their new design? And if this is such a great way to put XML into a file, why don't they make it apply to files in general rather tha restricting it to config files? Is there some hidden capability that I'm unaware of that only applies to the XML in application sections of config files which this design somehow caters to? And if you want a design that turns a structure into XML, isn't that precisely what XML serialization is all about? Why wasn't that used/expanded?

I'm a little confused as to the motivation behind all this seemingly needless complexity. Is there some explanation for it that somebody is aware of? 12/5/2006 5:03 PM | Darrell Plank
# re: Read/Write App.config with .NET 2.0/Enterprise Library
G'day,
Hi hope you can help,

We have recently started using Microsoft Enterprise Library and I'm trying to completely separate the database settings from my app by placing standard database functions & ldap directory lookup functions into a class.library.
This is to central all our standard routines etc into one place. This is fine and seems simple enough.

Problem arrises using Microsoft Enterprise Library & app.config within the class.library.

I can place all application settings into the app.config file within the class.library and these settings can be lookup and accessed without issue ie. LDAP_HOT_NAME and these sort of variable/settings. The problem comes when trying to add in database connect string via Enterprise Library Configration tool. If the database setting are created through here and saved into the app.config file I end up not being able to access the connection string, but can still grab the application settings etc. If i move the connectionstring items into the web.config file of the actual program (the program using the class.library) then the connectionstring can be found.

Is there anything to be aware off when trying to "centralise" these connectionstrings into the app.config of a class.library, or will Microsoft Enterprise Library only use the web.config file from the main program.

Hope this all make sense
Mark 12/19/2006 4:34 AM | Mark Vandersteen
# re: Read/Write App.config with .NET 2.0/Enterprise Library
Hi Mark,

the ConnectionsStrings property is a special one which is "hard" coded into the .NET App.Config schema like AppSettings. You do not need to create a special section for them and you can access you connection strings very easily via the ConfigurationManager.ConnectionStrings collection.
How did you access the connection string in your windows forms applicaton?

Yours,
Alois Kraus
12/21/2006 12:06 AM | Alois Kraus
# re: Read/Write App.config with .NET 2.0/Enterprise Library
How to edit the appSettings through Enterprise Library Configuration Tool v2.0?

Thanks
Anjan 1/5/2007 11:13 AM | Anjan
# re: Read/Write App.config with .NET 2.0/Enterprise Library
Hi Alois,

Many thanks for your really great article. I've been searching for days for information about this not very well documented part of dotnet.

My problem is the following: I am trying to read the app.config from a DLL (which is part of the application but not called from the application), because the DLL does not automatically read the app.config. When the DLL is called by an external thread, I want it to use the same configuration values, e.g. for tracing, like the EXE.

Thanks to your article I managed to read the app.config by using the following code:

Dim FileMap As New ExeConfigurationFileMap
FileMap.ExeConfigFilename = "app.config"
Dim Configuration As Configuration = ConfigurationManager.OpenMappedExeConfiguration(FileMap, ConfigurationUserLevel.None)
Dim SystemDiagnostics As ConfigurationSection = Configuration.GetSection("system.diagnostics")

But then I am stuck with lots of objects and elements which I would have to retrieve manually and load it onto the appropriate objects, e.g. TraceListeners.

I found the following framework class, which might do my whole job with one command, but Microsoft states it is deprecated.

DiagnosticsConfigurationHandler()

Do you know more or have an idea? I would really appreciate your help.

Oliver. 1/18/2007 3:48 PM | Oliver Hausler
# re: Read/Write App.config with .NET 2.0/Enterprise Library
Eugene wrote:

>I'm using .NET 2.0.
>I've included "using System.Diagnostics;"
>When I try >using "ConfigurationManager.AppSettings"
>I'm getting following error:
>"Error 8 The name 'ConfigurationManager' does >not exist in the current >context "C:/..../Test.cs".

Are you sure you should be programming?!! That error is like basic C# programming for beginners, day 1.
1/29/2007 4:56 PM | Waldy
# re: Read/Write App.config with .NET 2.0/Enterprise Library
Hi Waldy,

please note that
using System.Configuration;
and adding a reference to the System.Configuration assembly will fix your problem. System.Diagnostics will not help you to get a running program. A good way to find such things out is MSDN.

Yours,
Alois Kraus
1/29/2007 7:35 PM | Alois Kraus
# re: Read/Write App.config with .NET 2.0/Enterprise Library
Hi,
My solution has many projects, each one has a app.config file, which are correct.
However when i look at me solution.exe.config file, some values are out of date...


How do I resync the solution.exe.config file to contain all the correct values from the app.config files? 2/13/2007 4:31 PM | vick
# re: Read/Write App.config with .NET 2.0/Enterprise Library
Hi vick,

could you elaborate a bit what you mean with out of date? Did you change them (write them via the APIs) and nothing did happen?
Please note that if you step through your code with the VS2005 debugger you will change the App.vshost.exe.config file instead of you App.exe.config.

Yours,
Alois Kraus 2/13/2007 11:50 PM | Alois Kraus
# Read/Write App.config with .NET 2.0 / Enterprise Library
3/13/2007 11:59 AM | Alessandro's Blogs
# re: Read/Write App.config with .NET 2.0/Enterprise Library
hi
your article has been very informative to me as im still a student.
but i faced a problem with your code,the changes i made from the form are not reflected in the config file of my application,however when i restarts my application they are still shown. im not getting where they are getting stored .
need not to say your help will be highly appriciated
thank you 4/4/2007 6:57 PM | vikram
# Web 2.0 &amp;raquo; Blog Archives &amp;raquo; Adobe - Developer Center : Flash ActionScript 2.0 Learning Guide
Web 2.0 &amp;raquo; Blog Archives &amp;raquo; Adobe - Developer Center : Flash ActionScript 2.0 Learning Guide 4/19/2007 7:04 PM |
 
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值