2

I am struggling with how to persist preferences/settings/configurations that are read but also updated by my C# application. My configurations can be

  • individual ints, strings, byte[] that represent connection strings, directory names, file names,...
  • collections of strings or other value types.

  • class object instances that represent a group of mostly value types.

-> Such settings are accessed in different, sometimes unrelated classes.

I am currently pondering what you think is best practice, given the following bullet points:

  • A self-written key/value store. Internally the key/values are stored in a hashtable and the hashtable is serialized/deserialized for persistence.

  • Entity Framework: I have access to the MS entity framework and run MySQL server instances.

  • Text file / XML file

  • Any other/better ideas?

Exclusion:

  • I do not want to store any settings in Settings.settings, App.config, or the like

  • I do not want to use the registry

  • I do not want to store settings in any obscure roaming directory structures or other hidden directories. The settings should either be stored in a dedicated database/table or in the application executable folder or sub-folder.

Questions:

  • I am not sure whether to store all configuration objects in one and the same entity or whether I should setup several such entities to store groups of configurations?
  • what is the best way to persist such lightweight objects that function as settings/configuration and later load and access those?
Matt
  • 7,004
  • 11
  • 71
  • 117
  • Entity framework is definitely an overkill for storing preferences. I'd just use a `.json` file read and written to via [`System.Json`](http://stackoverflow.com/q/775692/458193) or [Json.NET](http://james.newtonking.com/projects/json-net.aspx) but that's me. XML is just as fine. – Dan Abramov Jan 11 '13 at 05:25
  • 3
    Why don't you want to use the types in the System.Configuration namespace? – Andrew Kennan Jan 11 '13 at 05:26
  • @DanAbramov, where would you store such file? Also I read collections can not all be easily serialized into XML or Json. That's why I persisted a dictionary or hashtable for example through serialization into binary. – Matt Jan 11 '13 at 05:27
  • @AndrewKennan, because I do not find it a clean solution, I do not want to mix up my configurations with MS specific ones. Additionally I want the data to still be accessible from the outside and through other apps. Digging through those App.config files just felt awkward. If I make the wrong assumptions then please correct me but how do I store a list or dictionary of strings in app.config? – Matt Jan 11 '13 at 05:32
  • @Freddy, you can extend the ConfigurationSection and ConfigurationElement types to customize the structure of the config files, you don't need to put everything into AppSettings. However, because you want multiple applications to be able to access the config, a database or some type of service application does sound more appropriate. – Andrew Kennan Jan 11 '13 at 05:53
  • @AndrewKennan, accurate, any recommendations of what people generally do in this case? A relational db sounds inappropriate because I have many instances of different types rather than one fixed structure where I would store/ access instances of such structure as is done with relational DBS. – Matt Jan 11 '13 at 06:11
  • @Freddy, I can't really say without knowing the details of your situation. Personally I would start by defining interfaces for accessing the data and worry about the implementation later. As you develop the system the appropriate solution may become obvious. – Andrew Kennan Jan 11 '13 at 06:24
  • @AndrewKennan, it starts to already here sound overly complex and time consuming. I currently run a persisted key/value store that operates on key/values of type Key and Value. Behind the scenes is a hashtable. It persists fine and reads fine, only issue is the boxing/unboxing which is fine. Plus I can't edit the data from the outside as they are in binary format. Is that horrible practice for apps in production? (I mean using dynamic instead of strong typing in this case? – Matt Jan 11 '13 at 06:28
  • @AndrewKennan, I mention your suggestion complicated because I am not in the business of designing a configuration manager but just need a stable key/value persistence of various object types subject to above restrictions. (no app.config or MS configuration mgr for mentioned reasons, I find it horrific to store settings in far away hidden folders that some weak backup programs omit to backup/restore, people forget to migrate, ..., its the number one reason why windows apps are so hard to migrate if you compare with android or apple apps, well, Win8 apps seem to change this slightly...) – Matt Jan 11 '13 at 06:30
  • @Freddy, my point was that starting with an interface with methods like "string GetConnectionString(string name)" rather than using a dictionary directly should make your code less error prone and easier to understand. Hopefully it would also provide insight into the best implementation. I might start with a simple implementation such as writing to an xml file somewhere. If that doesn't work the separation of concerns you get by using an interface should let you fix it without impacting on the rest of the system. – Andrew Kennan Jan 11 '13 at 06:49
  • @AndrewKennan, got it, thanks for your suggestions. Going the Xml route definitely sounds most reasonable to me at the moment. It has the advantage of being human readable over my binary key/value store. – Matt Jan 11 '13 at 07:01
  • @Freddy: If it was user-specific, I'd have stored it in Windows user data folder. If it was app-specific, I would have put it next to my app. Also +1 to human-readable formats. – Dan Abramov Jan 11 '13 at 12:30
  • @DanAbramov, the issue is that its neither user specific nor app specific. Imagine a solution that consists of several applications that communicate interproc, I want to store the tcp/ip ports on which each app is listening in one centralized location. So its neither user specific nor app specific. – Matt Jan 12 '13 at 06:53

2 Answers2

0

You can store your settings in WMI namespaces. We had stored one of our product specific settings and configuration there. Also though you have excluded App.config, Application specific settings would be normally stored therein.

stamhaney
  • 1,246
  • 9
  • 18
  • I want a dedicated storage location that is not mingled with other MS specific application settings and configs. – Matt Jan 11 '13 at 05:25
0

I would suggest using XML for this type of scenario.

  • It's easy to write and read

  • Human readable, and easy to open and edit manually

  • With LINQ to XML you can query for specific data and convert that data into strongly typed objects

  • Widely used and understood, especially for config files

  • Flexible structure

These are just a few things that come to mind. Here is some example code of querying the file for all protocols of type tcp.

XElement settings = XElement.Load("settings.xml");
IEnumerable<XElement> tcpSettings = settings.Elements("protocol").Where(o => o.Attribute("name").Value == "tcp")
// make some changes to the settings
settings.Save("settings.xml");

Edit:

Serialize Class containing Dictionary member

Community
  • 1
  • 1
Despertar
  • 21,627
  • 11
  • 81
  • 79
  • sounds most appropriate so far, but is it accurate that I cannot convert a .Net `Dictionary` to XML? I can serialize to binary but am not sure it works for XML? – Matt Jan 11 '13 at 06:18
  • also can I store many unrelated objects of completely different type in one and the same XML file? – Matt Jan 11 '13 at 06:20
  • yep, you can store all kinds of types in an xml file. You can manually read and write objects using LINQ, or you can use a DataContractSerializer which is fleixible xml serializer although the resulting xml may not be as human readable/neat. I've used it to serialize a Dictionary before, so you'll just have to try it. I'll edit the answer with a link to that. – Despertar Jan 11 '13 at 06:25