Thứ Năm, 13 tháng 9, 2007

Read/Write App.Config File with .NET 2.0








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 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("ModificationDate",
DateTime.Now.ToLongTimeString() + " ");

// Save the changes in App.config file.
config.Save(ConfigurationSaveMode.Modified);

// Force a reload of a changed section.
ConfigurationManager.RefreshSection("appSettings");
ShowConfig();
}
}
}



// 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);

// get all sections inside group
foreach(ConfigurationSection section in group.Sections)
{
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 learnt this little trick the rest is easy. Here is a little example that opens a file by specifying it's name, makes some changes to it and writes the changes to disk.

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 hides those strange things. Tom Hollander has a nice post explaining this already so I will not repeat the same here.

How To Read/Write Serialized Objects
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 whose content is de/serialized to the App.config file. I am going to show you at first the config file and then explain 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)




type="ConfigurationMigrationQuickStart.EditorFontData,
ConfigurationMigrationQuickStart, Version=1.1.0.0,
Culture=neutral,PublicKeyToken=null"/>





Most App.config files which contain config data have a element where many
are defined. The name attribute of a section (in this example "EditorSettings") tells the config system that the class ConfigurationMigrationQuickStart.EditorFontData is responsible for the ser/deserialization of the node . 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 for 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;

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

// You need to remove the old settings object before you can replace it
config.Sections.Remove("EditorSettings");
// with an updated one
config.Sections.Add("EditorSettings", configData);
// Write the new configuration data to the XML file
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.

Không có nhận xét nào: