How do I manage application configuration in ASP.NET?
I am having difficulty with managing configuration of an ASP.Net application to deploy for different clients. The sheer volume of different settings which need twiddling takes up large amounts of time, and the current configuration methods are too complicated to enable us to push this responsibility out to support partners.
Any suggestions for better methods to handle this or good sources of information to research?
How we do things at present:
- Various xml configuration files which are referenced in Web.Config, for example an AppSettings.xml.
- Configurations for specific sites are kept in duplicate configuration files.
- Text files containing lists of data specific to the site
- In some cases, manual one-off changes to the database
- C# configuration for Windsor IOC.
The specific issues we are having:
- Different sites with different features enabled, different external services we have to talk to and different business rules.
- Different deployment types (live, test, training)
- Configuration keys change across versions (get added, remove), meaning we have to update all the duplicate files
- We still need to be able to alter keys while the application is running
Our current thoughts on how we might approach this are:
- Move the configuration into dynamically compiled code (possibly Boo, Binsor or JavaScript)
- Have some form of开发者_开发百科 diffing/merging configuration: combine a default config with a live/test/training config and a site-specific config
Whichever way you go, I think it could be valuable to have the notion of a single "source of truth" for your configuration.
Duplication is fine, if you need to provide configuration to some components in their own specialized form.
But to retain your sanity I think you should try and aim to have one place where you set all the configuration pertaining to your application, and then a well-defined mechanism for translating that into entries inside Web.config, and any other config mechanism you have to support.
Depending on the level of skill of your support partners (whether or not they will break XML), I imagine you may also want to provide a GUI utility to let them twirl all the knobs in this "source of truth" configuration file, with "Apply" going and running transform/update code to make the necessary changes to Web.config & friends.
Then to manage your configuration for different sites/customers, you theoretically have around one configuration file to manage.
Note: In ASP.NET 4.0 a build-time configuration transform mechanism will be available (see http://blog.hmobius.com/post/2010/02/17/ASPNET-40-Part-4-Config-Transformation-Files.aspx), which may make this task easier. It appears you can use this with some hacks for non web projects (see http://philbolduc.blogspot.com/2010/03/using-config-transforms-outside-web.html).
However, if you need to make these changes at deployment time, you may be stuck with writing custom tools to do this, though it looks like the XDT transforms may be the way to go for you, given you want to be able to add/update/remove items.
If the code using said configuration items is code you manage/can change (and all running in managed code space/C#) I would look to porting the method calls that get settings to a call into a singleton-like class with at least a GetString() method on it.
GetObject() can be very useful (check out the .Net XML serialisation stuff - the Americans spell it with a 'z': serialization) ... useful for lots of stuff but also because it means you can start packaging related configuration items into single entries in the store.
As regards using a single store (a database table with cached access) or use your new configuration facade only to encapsulate where the configuration items are stored - that's up to you ... I strongly prefer a single store per product deployment for configuration because then you always know exactly where to look and where to make changes. All the web service references (WCF or otherwise) can be constucted and called using runtime-supplied strings ... :)
In terms of caching values for keys - I use my own in memory cache (for smaller apps) because the overhead on the stack is manageable ... things like memcache might work here (config store is accessed over TCP/on the network somewhere) ...
EDIT Something like:
public class ConfigurationStore
{
private static ConfigurationStore _instance = null;
public static ConfigurationStore Instance {
get {
if(_instance == null)
{
_instance = new ConfigurationStore();
}
return _instance;
}
}
public string GetValue(string key)
{
....
}
public Object GetObject(string key)
{
...
}
}
You may consider looking at NAnt scripts for automation combined with some custom .net utility to manipulate config keys.
精彩评论