I want to get some thoughts on best practices around making .NET app configuration environment-neutral.
Background. Some background first. I come from the Java world, not the .NET world, and in Java there are certain things that we can do to build packages that are environment-neutral. They are generally based on abstracting the configuration in some fashion. Here are a few examples:
- JNDI allows apps to reference enterprise resources (e.g., databases, JavaMail sessions, JCR repositories, etc.) by name, and then the name is mapped to a specific configuration according to the environment (dev, test, prod).
- Another example would be properties files. You might have a bunch of properties (e.g., "encryption_key", "smtp.server.url", "admin.email", etc.) that the app grabs from a properties file in a known location when the app starts up. The property keys are mapped to different values depending again on the environment.
- Some app development frameworks (like Spring) know how to pull properties files in so the properties can be integrated with the framework configuration.
Another approach I've seen in Java is a build-time approach, where you use Ant (token substitution) or Maven (build profiles) to build environment-specific packages. I don't like this approach quite as much just because I strongly prefer to deploy exactly the same package to test and prod. But it's an approach I've seen.
Desired solution. I'm assuming that in .NET there are some comparable strategies for decoupling a configuration (and by extension the containing package) from its environment.
Ideally I'd like a solution that allows me to keep non-environmental configuration closely associated with the app, externalizing only the environmental stuff. To go back to the Java examples, a lot of times the "configuration" is really something that the developers control, such as including a Sitemesh servlet filter for page decorations, dependency injection or app wiring, mapping such-and-such MVC controller method to a request URI, etc. That stuff I don't want to be externalized. But encryption keys, DB connection strings, log levels and so forth, yes.