1

what is the best way to save configuration data in c# application? note that those data maybe changed dynamically. as i know, ConfigurationManager class can be used. but i heard that this is not good way to do that.

  • 1
    I suggest Application Settings and User Settings: https://msdn.microsoft.com/en-us/library/bb397750(v=vs.110).aspx – ne1410s Dec 12 '15 at 10:18
  • 1
    _"what is the best way"_ - implies opinion and therefore is arguably off-topic for SO –  Dec 12 '15 at 10:46

3 Answers3

1

A simple way is to use a config data object, save it as xml file with the name of the application in the local Folder and on startup read it back.

Here is an example to store the position and size of a form.

The config dataobject is strongly typed and easy to use:

[Serializable()]
public class CConfigDO
{
    private System.Drawing.Point m_oStartPos;
    private System.Drawing.Size m_oStartSize;

    public System.Drawing.Point StartPos
    {
        get { return m_oStartPos; }
        set { m_oStartPos = value; }
    }

    public System.Drawing.Size StartSize
    {
        get { return m_oStartSize; }
        set { m_oStartSize = value; }
    }
}

A manager class for saving and loading:

public class CConfigMng
{
    private string m_sConfigFileName = System.IO.Path.GetFileNameWithoutExtension(System.Windows.Forms.Application.ExecutablePath) + ".xml";
    private CConfigDO m_oConfig = new CConfigDO();

    public CConfigDO Config
    {
        get { return m_oConfig; }
        set { m_oConfig = value; }
    }

    // Load configfile
    public void LoadConfig()
    {
        if (System.IO.File.Exists(m_sConfigFileName))
        {
            System.IO.StreamReader srReader = System.IO.File.OpenText(m_sConfigFileName);
            Type tType = m_oConfig.GetType();
            System.Xml.Serialization.XmlSerializer xsSerializer = new System.Xml.Serialization.XmlSerializer(tType);
            object oData = xsSerializer.Deserialize(srReader);
            m_oConfig = (CConfigDO)oData;
            srReader.Close();
        }
    }

    // Save configfile
    public void SaveConfig()
    {
        System.IO.StreamWriter swWriter = System.IO.File.CreateText(m_sConfigFileName);
        Type tType = m_oConfig.GetType();
        if (tType.IsSerializable)
        {
            System.Xml.Serialization.XmlSerializer xsSerializer = new System.Xml.Serialization.XmlSerializer(tType);
            xsSerializer.Serialize(swWriter, m_oConfig);
            swWriter.Close();
        }
    }
}

Now you can use it in your form in the load and close events:

    private void Form1_Load(object sender, EventArgs e)
    {
        // Load config
        oConfigMng.LoadConfig();
        if (oConfigMng.Config.StartPos.X != 0 || oConfigMng.Config.StartPos.Y != 0)
        {
            Location = oConfigMng.Config.StartPos;
            Size = oConfigMng.Config.StartSize;
        }
    }

    private void Form1_FormClosed(object sender, FormClosedEventArgs e)
    {
        // Save config
        oConfigMng.Config.StartPos = Location;
        oConfigMng.Config.StartSize = Size;
        oConfigMng.SaveConfig();
    }

And the produced xml file is also readable:

<?xml version="1.0" encoding="utf-8"?>
<CConfigDO xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
  <StartPos>
    <X>70</X>
    <Y>278</Y>
  </StartPos>
  <StartSize>
    <Width>253</Width>
    <Height>229</Height>
  </StartSize>
</CConfigDO>

Very simple, or what so you think?

Dieter Meemken
  • 1,937
  • 2
  • 17
  • 22
  • 1
    Don't do that. Use the very well integrated settings mechanism that's already built into the framework. – Thorsten Dittmar Dec 12 '15 at 10:42
  • I have to admit, seeing your answer posted so quickly, I wondered if it was plagiarism. Then I realised you posted the same thing [here](http://stackoverflow.com/a/33917532/1364007). :) – Wai Ha Lee Dec 12 '15 at 10:43
  • @Lee No, it is wirten my me, originally for an other post. So ist was ready by hand. – Dieter Meemken Dec 12 '15 at 11:02
  • @Thorsten The nice think about this is, that you have data object with strong type savety by the compiler and the possibility for xcopy deployment. – Dieter Meemken Dec 12 '15 at 11:03
  • I realise that. :) you're probably better off flagging the post as a duplicate (I did) if you think an old answer of yours will answer the question. – Wai Ha Lee Dec 12 '15 at 11:03
  • Settings mechanism is also type safe. And it supports all sorts of deployment. Esp. ClickOnce is not possible with your solution and automatic settings upgrades are also not supported. – Thorsten Dittmar Dec 12 '15 at 11:14
1

Use the built-in settings mechanism. But leave the configuration manager alone and use your settings like

Properties.Settings.Default.x 
Thorsten Dittmar
  • 55,956
  • 8
  • 91
  • 139
0

There is nothing wrong in using the ConfigurationManager (web.config/app.config). For different types of configuration data, I recommend the following;

  • Never-changing read-only configuration data

    • Hardcode in application or use (assembly-level) attributes. This requires a recompile/re-installation of app when configuration-data changes.
  • Almost never-changing read-only configuration data

    • Use the <appSettings>, <connectionStrings> or other sections in web.config/app.config (Often requires a restart of app when changed, especially when configuration-data is read only during startup)
  • Server-side writable configuration data maintained in application

    • Use a database or a file in C:\ProgramData\<name of your company>\<name of your app>
  • Client-side writeable configuration data maintained in application (desktop-apps)

    • Use a file in C:\Users\<clients login name>\AppData\Local\<name of your company>\<name of your app>\. If you need configuration data to be available on other computers (using the same AD domain), use the LocalRoaming folder under AppData instead (don't place too much configuration data in files placed here, tho because they need to be transferred between computers)
Frode
  • 3,325
  • 1
  • 22
  • 32
  • I was under the impression that you should stick to ConfigurationManager if you only do "normal" configuration. If you need Asp.net specific configuration mechanisms (like configuration inheritance) then switch to WebConfigurationManager. By using the ConfigurationManager only it's easier to use class-libraries in desktop and web scenarios without having to check what environment your code is running in. – Frode Dec 12 '15 at 11:12
  • Just quoting what's in the manual. I agree though, it's absolutely ridiculous that a _configuration system_ be tightly coupled to the _type_ of application one is making. Give me isolated storage and binary writers any day. –  Dec 12 '15 at 15:40
  • 1
    Thumbs up for that :) – Frode Dec 12 '15 at 15:55