Using a Static Member to Hold the Configuration Object
The example above uses a new class instance to load the WebStoreConfig class. Although this works, it's also very inefficient and takes extra work on your part. You really don't want to have to create an instance of this class each time you need to access one or more values. Nor do you want the class to have to retrieve and convert each of the values each time you instantiate it.
Instead it's best to use a static member to store this Configuration object. By using a static member, you can create the Configuration object once and leave it on the static property, which is always accessible to the application. Using a static constructor
(see sidebar) it's possible to have the Configuration object load up automatically the first time that it is needed.
So, let's hook up our Configuration object somewhere as a static member. I like to use a class called App in all of my applications. I use App rather than any of the preexisting Framework classes (such as the Global class in ASP.NET applications) so that I can reuse the object in multiple applications regardless of whether it is an ASP.NET or WinForm application. I usually store this class in my business objects project. A simple example of the App class with the Configuration object is shown in Listing 2
. Normally, this class has other "global" static properties that are used in the applications, but for demonstration, I only showed the Configuration member.
Notice the use of a static constructor (static App()
). This constructor fires the first time you access the Configuration object or any other static property or field of this class. Static constructors fire exactly once for the lifetime of the application and on the first access to any object of that particular class instance, which makes them very useful as loaders for propertiesjust like the configuration objectthat require only a one time initialization. With this constructor in place, you can use the following syntax from anywhere in your code:
decimal TaxRate = App.Configuration.TaxRate;
There's no object instantiation and no fuss, and you end up with a cached Configuration object. Static properties and static constructors are a very cool and useful feature.
Changing the Properties of the Configuration Object
You can also set properties of the Configuration object by simply assigning a value:
App.Configuration.TaxRate = 0.05M;
Keep in mind that when you're setting a value, it is only changed in memory and not automatically persisted back into the configuration file. If you want to write all changes to the configuration to disk, you can call the WriteKeysToConfig()
This method is static so you also don't need an instance to call it. If you are running ASP.NET, calling this method updates Web.config
, which has the same effect as manually editing Web.config
; ASP.NET shuts down and restarts the currently executing Application (unloads and reloads the AppDomain) to reflect the changes that were made to Web.config
|The wwConfiguration class allows you to access a configuration setting as a property.|
This behavior of ASP.NET is very useful. The application shuts down and restarts, and your static constructor gets fired again when you first access the App.Configuration object. This means you lose nothing by using this class: you still get notified of changes in Web.config
even when the file is manually edited or edited by another program. Cool!
Remember that in a multi-threaded environment, a static instance is shared among all threads. This means that all ASP.NET threads see the App.Configuration object. You need to be careful when writing data to properties or fields. Configuration information is mostly read, not updated, so you probably don't have to lose any sleep in this case, but keep this in mind as you're dealing with static properties in general.
Alternate Configuration Storage with Serialization
You can also write the configuration information to an alternate store instead of a config file and its AppSettings
section. By calling an alternate constructor, you can prevent the class from reading values on load, and instead use serialization to read and write the contents of your object. I find, for WinForms applications, it's actually easier to use this mechanism because of the way app.config
works (or doesn't work <g>) inside Visual Studio. VS .NET overwrites the config file each time the application runs, which makes it impossible to persist settings written at runtime, so using a different file to store settings makes development with these settings easier.
All you need to do to create a separate XML file is to create the class like this:
public class WebStoreConfig : wwAppConfiguration
// *** Override the constructor to do nothing!
public WebStoreConfig(bool NoLoad)
... property interface here
Add the Serializable
attribute and add a new constructor that doesn't call back into the base class, to prevent the default from loading from the configuration file. To write out the configuration data, you can use a method in the wwUtils class in your source code that allows XML (or binary) serialization:
You perform deserialization like this:
App.configuration = wwUtils.DeSerializeObject(
if (App.configuration == null)
App.configuration = new WebStoreConfig();
If deserialization returns null, the file didn't exist or the XML format was incorrect. In that case, you need to create a new instance and use the default values. This mechanism uses standard .NET serialization to write and read to an XML file. Using Serialization is very easy and one of the very handy features of the .NET Framework. You can review the handful of lines of code in the wwUtils class of the source provided.