views:

1568

answers:

4

Hi,

I want to have some custom configuration (read in from file) available throughout my C# windows forms application.

Is the concept of say:

  1. creating a static class, e.g. "public static class GlobalData"
  2. loading from from the "Load" action of the main form event

How does this sound? Is this the best practice way to do it?

+1  A: 

Look up ConfigurationManager.AppSettings.

Sample code at http://msdn.microsoft.com/en-us/library/system.configuration.configurationmanager.appsettings.aspx

Philip Davis
What about the built-in Settings mechanism? It's a lot cleaner than `AppSettings`.
John Saunders
Hmm, I've only ever used the ConfigurationManager. The notation in code is very clean. However the app.config files can get quite ugly.
Philip Davis
Similar to the previous suggestion, given my actual config I want to access is XML files created/loaded via serialization, I'm still not really sure how you're suggesting that I load/give access to my winforms program, via use of User or Application settings approach?
Greg
+1  A: 

I would hesitate to use a 'GlobalData' static class as it smacks of a generic Utils-type catch-all class which can end up being a dumping ground for all kinds of junk. I would lean more towards using the Windows Forms Settings (whether User or Application settings) to store my configuration information. Then, your configuration data can be retrieved from anywhere in your Winforms project using Properties.Settings.Default.MySetting.

With that said, there are some things that I may save in a static class. For example, I have a static SqlDBConnectionInfo object that contains my server, database, and credentials which may be used for making an Sql Connection object or for doing SMO backup/restore operations. This static object gets instantiated on login and any other class that needs to work with the SQL database in some way can grab the static object.

Edit: One other possibility is if you are deserializing/serializing your configuration data using an instance class, you could create a static property in your Program.cs that would hold the instance of your deserialized configuration object. Then, other classes in your project can refer to your configuration data using: MyProjectName.MyConfigurationObject.

C-Pound Guru
Given my actual config I want to access is XML files created/loaded via serialization, I'm still not really sure how you're suggesting that I load/give access to my winforms program, via use of User or Application settings approach?
Greg
@Greg: I was suggesting you move your configuration info into the Project's Settings (right-click Project->Properties->Settings tab. If this isn't feasible, see my last edit.
C-Pound Guru
+2  A: 

As others have stated, you can use AppSettings to store simple data. The basics are easy; going beyond them is hard (see App.Config and Custom Configuration Sections). You can also serialize classes to XML or JSON, write custom storage formats, use databases, etc.

Making the configuration available throughout your application is a separate issue. Static classes and Singletons are inherently difficult to test, and introduce coupling throughout your other classes. One option is to create an interface for your configuration data class, create and load the configuration on startup, then pass the interface to any class that needs it (often as a constructor parameter). This is called Dependency Injection.

If you're doing this a lot, there are libraries that will make it easier (after you get past the learning curve). See List of .NET Dependency Injection Containers (IOC).

TrueWill
thanks - what do you mean exactly by "then pass the interface"? I like your suggestion of some decoupling but not going the hold hog to a full dependency injection framework (which would be overkill).
Greg
@Greg: So your Foo class needs to access a configuration parameter. Load or Main creates the MyCustomConfig class and calls its Load method (or however you have it defined). MyCustomConfig implements interface IMyCustomConfig, which exposes all the properties. Your Foo class would then have a constructor of Foo(IMyCustomConfig config). If Load/Main creates Foo, it passes its instance of MyCustomConfig to it. If Foo creates Bar and Bar needs a config, Foo passes its config to Bar's constructor and so on. If you have a lot of levels, then consider a DI framework.
TrueWill
+1  A: 

I use the default Settings file for simple values like window locations and sizes. It's nice because the settings are compiled into properties for you. You can implement the other settings any way you like. I do not use application settings files very often in winforms. I used them all the time in asp.net. Sometimes, I store information in DataTables in memory and use the DataTable.Load and WriteXml functions to persist the information. Regarding global access, In winforms, I add a Component class to the project and create a global static instance in Main. I can then reference the instance from all forms and add global data to this component. The data is exposed as properties or via functions.

Steve