Share via


Configuring a Single Service Across Multiple Environments

Applies to: Windows Communication Foundation

Published: June 2011

Author: Alex Culp

Referenced Image

This topic contains the following sections.

  • Connection Strings and Remote Hosts
  • Configuration Transformation

Even a single WCF service can require a great deal of configuration. In addition to the service model's configuration, you can also have connection strings, application settings, and possibly configuration settings for Enterprise Library application blocks. A complex service can have hundreds of lines of configuration. Some portions will be different from one environment to another, and some portions will be common to all environments. In this situation, it may still be useful to separate configuration sections into separate configuration sources. However, you may find that managing multiple environment-specific configuration files is still very tedious.

Connection Strings and Remote Hosts

The same connection strings are often used by all environments. There are several ways to manage changes to connection strings. One solution is to update the host files on the servers where the services are deployed. The host file is located in %WINDIR%\System32\drivers\.... A new host entry resolves to the specified IP address, regardless of what is configured in the Domain Name Service (DNS). While this approach means that you only need to update a single file, it has some drawbacks.

First, if a database server changes its IP address, the host file on every server that uses that database server must be changed. Second, this approach requires that every database server listen on the same port. Third, this approach works for hosts but does not solve the general problem of how to change environment-specific configuration information. For example, in a production environment, you might not want to have exception details exposed in faults, while in another environment, such as QA, this information is very useful. Because of these drawbacks, this approach is not recommended.

Configuration Transformation

The Microsoft® Visual Studio® 2010 development environment has a new configuration transformation model that automatically modifies Web.config files by using a transformation file during deployments. This feature is particularly useful when you deploy a single service to multiple environments. It allows you to specify a base set of configuration information, and then define a delta for each environment. For more information, see "Web Deployment: Web.Config Transformation" at https://blogs.msdn.com/b/webdevtools/archive/2009/05/04/web-deployment-web-config-transformation.aspx.

Often, developers need to run particular builds, such as a QA build, or a staging build, from their workstations. Updating the configuration manually, each time that you need to direct the source code to a new environment, can be very tedious and error prone. Fortunately, you can automatically change your configuration by making a minor edit to your .csproj file. You cannot use the designer to do this. You must edit the XML.

Here is an example of how to use Visual Studio to perform this edit. The example follows the best practice of breaking the configuration into separate files.

Example: Updating Connection Strings

Note

The convenient Visual Studio menu item, Add Config Transforms is only available on Web.config files. You must create these files yourself.

  1. In Visual Studio, create a build configuration for each of your environments. Do not forget the Debug configuration for the local developer workstation. For more information about how to set up build configurations, see "Configuration Manager Dialog Box" at https://msdn.microsoft.com/en-us/library/t1hy4dhz(v=VS.100).aspx.

  2. If it does not already exist, create a new folder named Config at the root of your service.

  3. Create a single configuration file in the Config folder and name it ConnectionStrings.environment.config.

  4. Add a placeholder connection string for each of the connection strings. You only need names because they will be replaced in another step. The following XML code is an example of a placeholder.

    <connectionStrings>
      <add name="MyDatabase"/>
    </connectionStrings>
    
  5. Create an environment-specific configuration file for each environment, including Debug. The following figure illustrates an example of the hierarchy.

    Referenced Image

  6. You might be a bit overwhelmed by the number of configuration files. You can group these files under the root environment configuration file. One way to do this is to edit the project file directly. An alternative is to use VSCommands for Visual Studio 2010. The following figure illustrates the new hierarchy.

    Referenced Image

  7. In order for the transformation to work in a configuration source, you must add a namespace reference to the document transform XML Schema Document (XSD). Open the ConnectionStrings.Debug.Config file and add the following XML code.

    <connectionStrings xmlns:xdt="https://schemas.microsoft.com/XML-Document-Transform">
    </connectionStrings>
    
  8. You can now add a configuration transformation for each connection string in the root file (ConnectionStrings.environment.config). The following XML code is an example of what the new file should look like.

    <connectionStrings xmlns:xdt="https://schemas.microsoft.com/XML-Document-Transform">
      <add name="MyDatabase" connectionString="Data Source=localhost; Initial Catalog=MyDatabase;" providerName="System.Data.SqlClient" xdt:Transform="Replace" xdt:Locator="Match(name)"/>
    </connectionStrings>
    
  9. Edit all of the other environment-specific configuration files, as you did in step 7.

  10. After you have edited all of the configuration files, ensure that the correct connection string file is generated, based upon the active configuration. To do this, you must edit the project file. Right-click your project, and select Edit [Name of your Project].csproj. At the bottom of the file is a set of commented out build targets. Uncomment these and add the following configuration transformation step.

    <Target Name="AfterBuild">
      <TransformXml Source="$(ProjectDir)Config\ConnectionStrings.Environment.config" Transform="$(ProjectDir)Config\ConnectionStrings.$(ConfigurationName).config" Destination="$(ProjectDir)ConnectionStrings.config" />
    </Target>
    
  11. Build your solution with the build configuration of your choice.

  12. In the Project menu, select Show All Files.

  13. You should now see a ConnectionStrings.config file at the root of your service. The following figure illustrates an example of the project structure.

    Referenced Image

You can apply the same procedure to any configuration source, such as your service model configuration, application settings, or Enterprise Library application block configurations.

Previous article: Configuration Strategies

Continue on to the next article: Common Configurations