I am writing a program that need to store some configuration information. I thought XML would be a good choice, but I do not want to learn XML in C# from scratch.
Could you recommend good ways/classes handling this task?
I am writing a program that need to store some configuration information. I thought XML would be a good choice, but I do not want to learn XML in C# from scratch.
Could you recommend good ways/classes handling this task?
Just use the built-in .NET configuration system! What's wrong with that??
For that, add a reference to System.Configuration
to your project, and have a good look at the ConfigurationManager
class in that namespace.
Starting with Visual Studio 2005, you can also define application- or user-scoped settings in a visual designer inside VS - check out Application Settings Overview on MSDN for this (those work for Winforms and console apps). Those settings are stored in your app.config
/web.config
for the application-scoped settings, and in a separate user.config
file in a directory accessible to the user account for the user-scoped settings. Those can be manipulated and updated at runtime using standard .NET classes (from the System.Configuration
namespace).
While I agree that "re-inventing the wheel" is not a good idea, the .NET System.Configuration class is abominably difficult to use for such a simple task.
I needed to create separate configuration files that could be specified on the command line for one of my programs (instead of just default assuming it would be "app.config") so I used this simple class - which saves itself to an XML file.
Here's a simple little snippet to get you started. You don't need to know any xml...
internal static string GetConfigSetting(string settingName)
{
return ConfigurationManager.AppSettings[settingName].ToString();
}
internal static bool GetConfigSettingBool(string settingName)
{
string setting = GetConfigSetting(settingName);
if (string.IsNullOrEmpty(setting)) return false;
bool value = false;
if (bool.TryParse(setting, out value))
return value;
else
return false;
}
internal static string[] GetConfigSettingsArray(string settingName)
{
return GetConfigSetting(settingName).Split(',');
}
internal static DateTime? GetConfigSettingDateTime(string settingName)
{
string setting = GetConfigSetting(settingName);
DateTime retval;
if (DateTime.TryParse(setting, out retval))
{
return retval;
}
else
{
return null;
}
}
internal static void SetConfigSetting(string settingName, string value){
ConfigurationManager.AppSettings[settingName] = value;
}
I've been using an XML configuration type setup for some time now, which is run off the built in configuration, which is sort of neat. Basically, you can give it a hint, and it'll deserialize the xml right into an object for you. I think the original source I got this from was here, but i'm not 100% sure, so if someone does know the author, please edit my reply to give proper credit.
Here's the class that actually does the deserialization:
using System.Configuration;
using System.Xml;
using System.Xml.Serialization;
using System.Xml.XPath;
namespace Ariel.Configuration
{
class XmlSerializerSectionHandler : IConfigurationSectionHandler
{
public object Create(object parent, object configContext, XmlNode section)
{
XPathNavigator nav = section.CreateNavigator();
string typename = (string)nav.Evaluate("string(@type)");
Type t = Type.GetType(typename);
XmlSerializer ser = new XmlSerializer(t);
return ser.Deserialize(new XmlNodeReader(section));
}
}
}
Now, you can create any class you want for configuration.
namespace MyProject.Config {
public class TestConfig {
/// <summary>
/// Whether the session is enabled
/// </summary>
public bool Enabled { get; set; }
}
}
Now, all you need is an app.config file. I generally prefer a style to use a separate configuration file for each configuration class, so I'll give you that as an example.
<?xml version="1.0"?>
<configuration>
<configSections>
<section name="TestConfig" type="Ariel.Configuration.XmlSerializerSectionHandler, Ariel"/>
</configSections>
<runtime>
<gcServer enabled="true"/>
</runtime>
<TestConfig configSource="Config\\TestConfig.config" />
<startup><supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.0"/></startup></configuration>
The Important parts are: section name = "TestConfig" <- The configuration class type=Ariel.Configuration.XmlSerializerSectionHandler, Ariel <- The type which is used to deserialize are xml in an object. This basically tells the configuration manager what to run to create our object TestConfig configSource="Config\TestConfig.config" <- This tells us where to find the configuration file for the section TestConfig.
In you're TestConfig.config file you would have something like this:
<?xml version="1.0" encoding="utf-8" ?>
<TestConfig type="MyProject.Config.TestConfig, MyProject">
<Enabled>True</Enabled>
</TestConfig>
Again the important part is the reference to the class name and the Type.
Last but not least, to load you're configuration:
using System.Configuration;
Config.SessionKillConfig config = null;
try {
config = (Config.SessionKillConfig)ConfigurationManager.GetSection("CdrAnalyzerConfig");
} catch (System.Configuration.ConfigurationException ex) {
syslog.Fatal("Loading parser configuration failed", ex);
return;
}
if(config.Enabled) { //do stuff }
This may be a little long winded, but the thing is, it's quite portable. Basically, to include configuration, all you have to do is write a class, and then write an xml file that matches that.
I'm not 100% sure how to pass the configuration file as an parameter to the program, but I imagine there is an option in the ConfigurationManager class somewhere for that. I even think I read somewhere that someone was working on having it detect changes to the file and reload new configuration into the running program, but I haven't tried anything like that. Anyways, I hope the example is useful for one approach you can take.