In a previous post series I wrote about Configuration DSLs – I’m now just looking at this from another angle of going back to some reading about the microsoft mechanism itself.
A quick note about the previous approach. The configuration is centralised into one
Configuration object and then the application has this available. This is similar to Microsoft approach because we have
ConfigurationManager available everywhere. The problem for me is that with
ConfigurationManager the central configuration point is the app.config and that is how developers expect the application to work – working against such conventions is often creates more friction than is necessary.
Therefore, if you can’t use a (replace the) central configuration object as above, you need to have multiple xml settings. But how? Microsoft has a design time changer – the app designer. AFAIK this works when you deploy from your design environment. That is far from ideal and means that you create a build per environment. I often see this often or something that approximates this approach. But it does not lend itself to a build server. Here’s a well documented approach that can work in both design and deploy time with some adjustments as this one is design time only and we would need to implement the same code in the
deploy.proj for msbuild
So the next approach which I have used is to update through xml replacements. This is easiest done replacing entire xml files which are includes into the main xml file. This can be done easily at deploy time. The problem is that all environment settings are shipped. In the situation where the package is for the one client – this isn’t actually a problem. The question is the switching mechanism to swap over xml files. There is the other issue of reconciling differences between environment settings.
This leads to a solution of having all settings in the same file. This approach is outlined in Creating Custom Configuration Section which I mentioned below. This approach could work well for the settings in your application. For example, using a proxy, I hook this up myself with my
WebRequest. However, this approach wouldn’t work for
log4net settings. So, we still need a better approach for specifying settings in different environments.
Where I want to head is to write a wrapper that manages writing out the xml from C# configuration. This would allow a management strategy that works with the current approach, but could also work in the first mode too of providing its own configuration references. Because settings are in C# they are hidden unless needed. Using an approach like migratordotnet we interrogate the dll for the settings and make updates at deploy time. This interrogation can take the form of dry-run, diffs, updates, backups.
Configuration is a complex and has many views. All those view combined often leads to mistakes so we need it to be as simple as possible. Very simple approaches have often resulted in cut-and-paste management – I think this is simplistic and error prone. As a developer, I understand that for my application I need a way to extend my reach into the production environment and yet give operations enough control for customisation. Because I certainly don’t want to do overnight support, nor do I want to know the credentials for production systems.
There is a final issue. How do we know what environment we are in? (and what are these called? – local, build, test, prod) Given windows conventions and mixed in with a little *nix I would go with this:
- System environment variable – in C# accessed through a registry key and batch (eg
- Process environment variable – eg passed in via commandline and used in say
app/web.config– I would use this other than it has been update from one of the above (if you are using this it is likely that it was manually set)
Note: I think that for enterprise type solutions (only one production deployment) we do know about every environment that we are deploying to. If not, these ideas are not for you because you have multiple deployments (customers). To me, this is consumer-type software and requires that installers can manage themselves.
 – General about ConfigurationManager
If you want to learn about configuration then here is the key series by Jon Rista on The Code Project
- Unraveling the Mysteries of .NET 2.0 Configuration
- Decoding the Mysteries of .NET 2.0 Configuration
- Cracking the Mysteries of .NET 2.0 Configuration
 – Creating custom configuration sections for environment
- App.Config and Custom Configuration Sections
- Creating Custom Configuration Section for each environment
- example to provide environment specific settings (dev through to prod)
- implementation is for runtime switching
- use a custom implementation of AppSettings
- uses the machine.config for global settings
- an approach that requires a specific implementation and xsd updates. Good example that the current implementation is limited and customisations are complex.
- design time checking through xsd (rather than intellisense)
 – using compile/deploy time switching
- Swapping out configs
- Handling Multiple Environment Configurations with .NET 2.0
- Managing Multiple Configuration File Environments with Pre-Build Events
- Managing Multiple Environment Configurations through NAnt
- Post Build Deployments with MSBuild – using WebDeployment task ReplaceConfigSections
 – design time deltas with deploy time switching
- Enterprise Library Design Time Deltas
- Environmental Overrides in Enterprise Library 3.0
- Environmental Overrides in Enterprise Library 3.0 – Managing Development, Test, Staging, and Production Configurations Made Easy!
 – poking files*
- “XmlMassUpdate MSBuildCommunity Tasks”:
- “XMLpoke in nant”