0

I am thinking about a way to create a flexible "settings class" in C#. The question is: How to provide a confortable way to provide default values to the settings. I want the programmer to access the default settings as easy as possible using intellisense. Therefore I encapsulated the default values in a subclass of the actual settings class (instead of defining them directly in the settings class).

 public class ServerSettings
 {
    public ServerSettings(int port = ServerSettings.Default.Port,
                          string anotherSetting = ServerSettings.Default.AnotherSetting)
    {
        this.Port = port;
        this.AnotherSetting = anotherSetting;
    }

    public int Port { get; set; }
    public string AnotherSetting { get; set; }

    public class Default
    {
        public const int Port = 7000;
        public const string AnotherSetting = "abcd";
    }
}

The programmer now is able to access the default values like this:

ServerSettings.Default.Port

And after typing ServerSettings.Default a list with all available default settings will show up. It's like a "multitype enum".

What do you think of this solution? Do you have any alternative ideas? Or some criticism?

  • 2
    I'm not sure how exactly this is supposed to work--it's a flexible settings class, but it's got hard-coded defaults and a rigid implementation. What's the use case for this? – mgw854 Dec 30 '14 at 15:06
  • ok by "flexible" i mean it's extensible. nothing prevents you from loading them from a file. but if i don't want/need to provide that functionality, i need to have the values inside the code - and that's where that constants come to stage. this way, the properties are initialized with the default values AND the programmer has easy access to that default values if they are needed somewhere else. maybe i'm not doing a good job to explain the purpose of it - please let me know ;) – Stefan Woehrer Dec 30 '14 at 15:16
  • Why not implement the default values as constants on the class itself? A default parameter less constructor that uses the defaults, and a constructor with the required number of parameters for when you want to specify custom values. – Kami Dec 30 '14 at 15:19
  • In C# I'd go with msdn.microsoft.com/en-us/library/k4s6c3a0%28v=vs.110%29.aspx. You can do all the things you mentioned above with it, as well as save new settings, in a human readable file. Any serializable type can be used in it. – IdeaHat Dec 30 '14 at 15:28
  • @Kami that was my very first thought as well, but then I realized that this way you'd have to give "complex" names to the constants like Default<SettingName> plus those default values would show up with all other class members in intellisense. Call me pedantic :p but I don't like this hehe – Stefan Woehrer Dec 30 '14 at 19:24
6

It sounds like you're recreating the Configuration Management class that the .NET framework already provides.

One thing that I've seen done is to provide a wrapper class around the ConfigurationManager so that a default value can be specified in case the requested configuration parameter isn't present or isn't readable in the configuration file.

Using the .NET configuration class buys you a couple of benefits such as caching of the application properties, compatibility with threaded programs, and atomic operations with reading / writing to the configuration file.

  • You can use this article as a good primer on using System.Configuration; codeproject.com/Articles/16466/… – oɔɯǝɹ Dec 30 '14 at 15:53
  • thanks a lot. in my case, the server and the client applications both reference to a common class library (DLL). i want to have my (default) settings stuff there (so i won't have the same settings, eg. the port number, once in each application). but i think this was a good hint, since apparently it's possible to have an "app.config" file for DLL's too - i didn't know that :) stackoverflow.com/questions/5190539/… – Stefan Woehrer Dec 30 '14 at 19:19
2

What do you think of this solution? Do you have any alternative ideas? Or some criticism?

It's fine. Personally, I would just have a public static readonly instance on ServerSettings rather than the nested type. Then you can pass around ServerSettings.Default (or use it if someone passes in null somewhere). Plus it seems to be a little cleaner to me.

In C#, there's the built in stuff that people are used to, though I think is highly overrated.

You should probably mark this class as Serializable or with DataContract to make it clear that it's meant to be used that way. I would also make the object itself read only. Modifying settings at runtime is a dicey prospect that can easily go bad and is hard to reproduce.

All that said, I would encourage you to use settings infrequently. Too often people make their code configurable when it's never going to change. It's straightforward, but it's also one more tidbit of complexity - one more thing that can go wrong. It makes your code more brittle.

I would also encourage you to break up your settings. Having one giant settings blob is convenient, but it's also a short and easy path to a coupling nightmare. Let things know about what they need to know about and no more, just like any other data.

  • many thanks for your answer - i learned a lot from it. as soon as i have enough reputation, i'll upvote it :D – Stefan Woehrer Dec 30 '14 at 19:21

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.