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:
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.
.NET executables and web applications by default implement .config files which do exactly what you describe. There's an entire namespace, System.Configuration, that deals with .config files.
Go look for reference material on App.config and Web.config. App.config is a generic term for an executable's default config file, which is named foo.exe.config, where foo.exe is the name of the executable. Web.config applies to web applications.