voithos
voithos

Reputation: 70552

Design guidelines for configuration system?

Most of my programming has been in web-based applications, although I have done some desktop application development for personal projects. A recurring design issue has been on how to manage the configuration. For example, we all know that in ASP.NET the web.config is used frequently to hold configuration information, whether it be generated or manually configured.

Before I even knew what design patterns were, I would implement what would be in essence a Singleton pattern. I'd write a static class that, upon startup, would read the configuration file and store the information, along with any auto-generated information, in fields, which were then exposed to the rest of the application through some kind of accessor (properties, get() methods...).

Something in the back of my mind keeps telling me that this isn't the best way to go about it. So, my question is, are there any design patterns or guidelines for designing a configuration system? When and how should the configuration system read the configuration, and how should it expose this information to the rest of the application? Should it be a Singleton? I'm not asking for recommended storage mechanisms (XML vs database vs text file...), although I am interested in an answer to that as well.

Upvotes: 3

Views: 1686

Answers (2)

Adrian K
Adrian K

Reputation: 10215

Guidlines:

Consider management of the settings

  • How often are they likely to be changed?
  • How can change them and how do they do it?

E,G web.config changes require someone with technical skill and result in your app being reset when it's changed; where-as settings accessed by a UI provided by the system won't have those issues.

Security

  • Do you need to encrypt any settings?
  • Do you need to segregate settings so that only certain people can access certain ones?
  • Do you need to provide any auditing of changes?

Naming Conventions

  • Do have some.
  • I strongly recommend using a URI based approach for setting keys - this helps to avoid collision between different settings between different components (likely when you start adding third party components to your system - or when your's is added to someone else's.
  • URI based keys also make it easy to maintain as it's easier to see what the setting applies to.
  • There are different naming "schema's" you can use, I like to mirror the code structure if I can, but sometimes you might want to follow something else like business proces.
  • Don't use ambiguous names like "DatabaseConnection".

URI based key example:

   <appSettings>
        <add key="Morphological.RoboMojo.BusinessLogic.IJobDataProvider" value="Morphological.RoboMojo.XmlDataProvider.JobDataProvider, Morphological.RoboMojo.XmlDataProvider"/>
        <add key="Morphological.RoboMojo.BusinessLogic.ITaskDataProvider" value="Morphological.RoboMojo.XmlDataProvider.TaskDataProvider, Morphological.RoboMojo.XmlDataProvider"/>
        <add key="Morphological.RoboMojo.XmlDataProvider.NameAndPathOfDataFile" value="C:\Program Files (x86)\Morphological Software Solutions\RoboMojo\RoboMojoState.txt"/>
        <add key="Morphological.RoboMojo.XmlDataProvider.PathOfDataFileBackups" value="C:\Program Files (x86)\Morphological Software Solutions\RoboMojo\RoboMojoState Backups"/>
        <add key="Morphological.RoboMojo.BusinessLogic.ITaskExecutorProvider" value="Morphological.RoboMojo.TaskExecutorMSRoboCopy.RoboMojo, Morphological.RoboMojo.TaskExecutorMSRoboCopy"/>
        <add key="Morphological.RoboMojo.TaskExecutorMSRoboCopy.LocationOfRoboCopyEXE" value="C:\Windows\System32\RoboCopy.EXE"/>
    </appSettings>

Upvotes: 1

DarinH
DarinH

Reputation: 4879

Not to sound like a cop out, but it's really going to completely depend on your app. Very simple apps (sounds like your talking about Web based apps so I'll skip fat clients), usually need nothing more than global config (you can use web.config and a singleton for that) and a per user config (a user table, and possibly a linked config table or name/value pair table can handle that.

More sophisticated apps might need a full hierarchy of configuration that's protectable and overridable. For instance, I might have several app defined defaults, that can be overridden for each group that a user belongs to, the user themselves and finally an administrator defined value for a specific group or user that can't be override by the user.

For that, I generally use a singleton "root config" object that has methods that expose additional levels of the hierarchy and config properties at each level. The root is responsible for resolving the heirarchy , but if necessary (for setting config for instance) you can traverse the heirarchy yourself to deal with settings specific to a single level in the heirarchy.

And finally, there's the issue of latency. If you expect config settings to change often, reading them from storage each time they're requested is best, but most expensive.

If not, you can cache settings, along with a "last read" date, and simply reread setting values into the cache after an expiry time.

Upvotes: 1

Related Questions