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?
5
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.
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.
1