Introduction
We have a couple of choices to work with applications in .NET 2.0:
|
Pros |
Cons |
appSettings section in standard configuration files |
- Simple existing API
- Changes in web.config immediately reflected in application
|
- Name-value string pairs only can be stored
- Application needs to be restarted to accept external changes
|
Custom configuration sections |
|
- Should be implemented for each configuration structure
- Implementation is not very intuitive
- Application needs to be restarted to accept external changes
|
applicationSettings section & Settings files |
- Standard API
- Built-in (in Visual Studio 2005) editor for simple types, support for design-time binding
- Writable from application code
- Complex types can be stored in
ArrayList
|
- Limited supports for complex types
- Application needs to be restarted to accept external changes
|
Challenge
So what would I like to have?
- I want to store and retrieve from configuration store arbitrary class.
- If configuration changes between two subsequent attempts to configuration, later access should reflect changes.
- I am too lazy to build implementation for each class, I'll have to store.
Solution
This solution is based on using XML configuration file in any convenient schema. Configuration consists of classes that represent data, stored in the configuration file and manager which is responsible to store, retrieve and cache configuration data. The manager uses simple XML serialization/deserialization to read/write data. Configuration file path is stored in standard application configuration file. System.Web.Caching.Cache
is used to cache configuration data.
And what about the implementation? To address my laziness problem, I built a simple utility to generate the whole implementation from the XML configuration file. All you need is supply the configuration file path, output directory and desirable namespace.
Using the Code
There are solutions with three projects in the source code archive that you can download. All actual code generation work is done in the DynamicConfiguration
class library. ConfigGenerator
is a WinForm utility that lets you select the configuration file and generate code from it. The last one is a sample project that demonstrates configuration usage.
Sample cnfg = SampleConfigurationManager.Data;
MessageBox.Show(String.Format("Configured screen width: {0}", cnfg.Screen.Width));
cnfg.Screen.Width = 640;
cnfg.Screen.Height = 480;
SampleConfigurationManager.Save();
Points of Interest
To build classes from an XML file, we need to create the XML schema first. Normally you can do it using the xsd.exe utility, from XML editor in Visual Studio 2005 or using other tool (XML Spy for example). The schema produced by xsd.exe was not good enough for me because it is compatible with dataset structure and will generate un-typed result in some cases. Try, for example, generate XSD and classes using xsd.exe from this simple XML:
<Test>
<AAA>
<Value>5</Value>
</AAA>
<BBB>
<Description>Sample</Description>
</BBB>
</Test>
To create a schema, I dropped XSD implementation (which simply loads XML into a dataset
and retrieves the schema using the GetXmlSchema
method) and used XmlSchemaInference
class instead. This class is a part of the System.Xml.Schema
namespace; it is supported in .NET 2.0, 3.0 and should not be overlooked if you have work with XML schemas.
Another point of interest is using System.Web.Caching.Cache
object. Apparently, a lot of people don't know that it can be used outside of Web context. The following code makes sure that it can be used both from a Web application and regular Windows application:
private static Cache cache
{
get
{
if (HttpContext.Current == null)
return HttpRuntime.Cache;
return HttpContext.Current.Cache;
}
}
History
- 7th August, 2007: Initial post