Getting Started

Firstly, I recommend that you clone the complete ConfigZilla repository from https://github.com/PhilipDaniels/ConfigZilla because it contains some Samples that demonstrate most of the ConfigZilla features. (Open the ConfigZillaSamples.sln in the Samples folder).

Install ConfigZilla using NuGet

From the package manager console, do

install-package ConfigZilla

or use the GUI:

Package Manager GUI

Install ConfigZilla into every project that you want to access your configuration settings from. This will do two things. The first and most obvious is that it will create a project called "ConfigZilla" in your solution and your other projects will be given a reference to ConfigZilla too. We'll take a quick tour in a moment. The second, and much less obvious, is that it will install an MSBuild ".targets" file into the .csproj of each project that you added ConfigZilla to. You can see this by right-clicking the project, selecting "Unload Project", then editing the project file. Down the bottom you will find a line like this:

<Import Project="..\packages\ConfigZilla.2.0.0\build\ConfigZilla.targets" />

That .targets file contains the instructions that will transform your *.template.config files into the final *.config files. It hooks into your build process so that the transformation will be made before your project builds. This means the *.config file will be ready and waiting for your build to rename to MyApp.exe.config or to publish. The transformation itself is based upon the contents of the ConfigZilla project, so let's take a look at that before we get into creating templates.

A Quick Tour of the ConfigZilla Project

Here's a screenshot of a typical ConfigZilla project. In fact, this is from the ConfigZilla samples.

The ConfigZilla project.

The newly-created project includes some examples to get you started: feel free to delete anything you don't need although it's a lot more likely you will be adding things.

The Transforms folder. This is where the clever stuff happens. There are two types of files. *.targets files are MSBuild files that are used to define properties. The value of the properties can be controlled using MSBuild Conditional statements, typically you check the $(Configuration) setting to figure out if you are in Debug, Release etc. The second type of file is the *.xslt file. These files use XSL Transformations to change XML. If you check the example appSettings.czDefault.xslt file you will notice it contains what looks like an MSBuild property expression, $(appSetting1):

<add key="Setting1" value="$(appSetting1)" />

In fact, that is exactly what it is. ConfigZilla works like this:

  1. The build of the ConfigZilla project begins. This will probably be first because most projects will include ConfigZilla so that they can reference the config settings. The contents of the Transform folder is ignored at this time.
  2. Compilation of projects that ConfigZilla is installed in begins (call it ProjectX). ConfigZilla loads all the *.targets files from under the ConfigZilla\Transforms folder and then, optionally, ProjectX\Transforms, and evaluates them in the context of ProjectX and the current build configuration. This results in each property being given a value. More on targets.
  3. Next ConfigZilla reads all the applicable .xslt files from under the ConfigZilla\Transforms folder and then, optionally, ProjectX\Transforms, and looks for property expressions $(likethis). If it finds one it replaces it with the value of that property as worked out during the previous phase. If there is no matching property then the text is just passed through as-is. ConfigZilla will always include a file called *.czDefaults.xslt and it will also optionally include another file if its name matches the current solution configuration: ProjectX.Release.xslt for example. But the expressiveness of the *.targets files means you usually only need the czDefaults file. More on transforms.. If you would like to see what ConfigZilla is doing try increasing the verbosity of MSBuild to "normal".
  4. All the *.xslt files are then concatenated together and written out, together with a bit of boilerplate, into a single file called ProjectX.ConfigZilla.xslt, which will be in the "obj" folder of the ConfigZilla project. You can examine this file in Visual Studio or a text editor if you want to check it; here is an example.
  5. That's all the hard work done. The ProjectX.ConfigZilla.xslt file contains all the information necessary to transform *.template.config into *.config. The next step in the build process simply finds all your *.template.config files and applies the Xslt to them using the built-in MSBuild target called XslTransformation, and writes the result to *.config.

Two points to note. Firstly the structure of the Transforms folder is not fixed: you can create subfolders to any depth you want, and with any name, ConfigZilla simply scans it recursively looking for *.targets and *.xslt files. Secondly, the property substitutions that ConfigZilla makes in the *.xslt files are simply MSBuild property values, this means that the full set of standard MSBuild properties such as $(Configuration) and $(MSBuildProjectName) are available to you and will be evaluated in the context of the project being compiled. A corollary of this, coupled with the fact that ConfigZilla amalgamates everything together, is that it is a a good idea to use a variable prefix such as "app" for app settings and "cs" for connection strings. This will stop any inadvertent clashes.

Strongly typed accessor classes. The C# files AppSettings.cs, ConnStrings.cs etc., are to be used within your solution to read the values of settings. They are in the namespace "CZ", but you can change this if you want. The classes here are only examples and ConfigZilla does not regenerate them. Example usage:

string connStr = CZ.ConnStrings.ConnStr1;

If you don't want some of the examples just delete them.

XsltSnippets.txt. This is a documentation file that includes various "snippets" or "recipes" for transforming XML with XSLT - tasks such as rewriting elements, setting their text values, or changing attributes. It is intended as a quick reference for the common operations to save you from Googling.

XmlDeserializeConfigSectionHandler.cs. This is a base class that can be used to quickly implement custom configuration sections. We will see an example below.

Using ConfigZilla in projects

The notes here apply to console applications, class libraries, test projects, WinForms applications and all other project types. Web apps give you a few more things to think about (see below). You don't have to do things in this order, you might start by preparing the .targets files for example, but all three steps need completing before templates will be processed.

1. Create your templates

Your final config files are created by copying a template and replacing some values in it. Template files are very easy to create - at a minimum all you need to do is copy a .config file and rename it as .template.config. But it's usually a good idea to blank out the values you will be replacing to prevent confusion about where they are coming from. More on creating templates.

2. Write your XSLT transforms to insert your values into your template

The job of the XSLT transformation is to take your .template.config file and transform it into a valid .config file. This is usually achieved by a combination of

You write the XSLT inside a file in the Transforms folder - this folder is special, ConfigZilla always looks for a folder of this name. However, you can split up your transformations into separate files, each one of which is responsible for a certain part of your config files. This helps to keep the files manageable. ConfigZilla will concatenate all your XSLT files together into one large file called ConfigZilla.xslt in the output folder. Read more about how to write the .xslt files. The *.xslt files used in ConfigZilla are special because you can have MSBuild properties substituted into them by using the syntax "$(AnyProperty)" (without the quotes). Arranging for $(AnyProperty) to have the right value is done in the .targets file.

3. Write your .targets files to set property values

The .targets file is where you create MSBuild properties and give them values. ConfigZilla dynamically loads your .targets file and evaluates it in the context of the project being compiled and the current solution configuration such as Debug, Release etc. You don't need to know much about MSBuild to write a valid targets file, but the important thing to note is that all properties are simple strings.

4. Write C# classes to provide type-safe access to your settings.

It's a good idea to write some C# classes to give you easy and type-safe access to your configuration settings. ConfigZilla contains examples for AppSettings and ConnStrings that need no further explanation:

/// <summary>
/// Class to return the AppSettings.
/// </summary>
public static class AppSettings
{
    public static string Setting1
    {
        get { return ConfigurationManager.AppSettings["Setting1"]; }
    }
    
    public static string Setting2
    {
        get { return ConfigurationManager.AppSettings["Setting2"]; }
    }
}

/// <summary>
/// Class to return the connection strings.
/// </summary>
public static class ConnStrings
{
    public static string ConnStr1
    {
        get { return ConfigurationManager.ConnectionStrings["ConnStr1"].ConnectionString; }
    }
    
    public static string ConnStr2
    {
        get { return ConfigurationManager.ConnectionStrings["ConnStr2"].ConnectionString; }
    }
}

These examples are created when you install ConfigZilla and are never overwritten, feel free to change or delete them as you see fit. The samples also contain two examples of custom configuration section handlers - a useful technique for grouping your application settings when they begin to grow. The ReportingSettings class looks like this:

public class ReportingSettings : ConfigurationSection
{
    // The string is the name as it must appear in the .config file.
    public static readonly ReportingSettings Current = (ReportingSettings)ConfigurationManager.GetSection("reportingSettings");
    
    [ConfigurationProperty("PageSize", DefaultValue = "20")]
    public int PageSize
    {
        get { return (int)base["PageSize"]; }
    }
    
    [ConfigurationProperty("Server", DefaultValue = "http://example.com/ReportRequest")]
    public string Server
    {
        get { return (string)base["Server"]; }
    }
    
    [ConfigurationProperty("RecipientEmail", DefaultValue = "phil@example.com")]
    public string RecipientEmail
    {
        get { return (string)base["RecipientEmail"]; }
    }
}

and allows you to create custom configuration sections that use the "attributes" style:

<configSections>
    <section name="reportingSettings" type="CZ.ReportingSettings, ConfigZilla" requirePermission="false" />
</configSections>

<reportingSettings PageSize="20" Server="http://Release.example.com" RecipientEmail="phil@Release.example.com" />

The PaymentSettings example class looks like this:

public class PaymentSettings : XmlDeserializeConfigSectionHandler
{
    public static readonly PaymentSettings Current = (PaymentSettings)ConfigurationManager.GetSection("PaymentSettings");
    
    public string PaymentSystem { get; set; }
    public string URL { get; set; }
    public int Timeout { get; set; }
}

and allows you to create custom configuration sections that use the "elements" style:

<configSections>
    <section name="PaymentSettings" type="CZ.PaymentSettings, ConfigZilla" />
</configSections>

<PaymentSettings>
    <PaymentSystem>Wordlpay</PaymentSystem>
    <URL>https://worldpay.releasemode.example.com</URL>
    <Timeout>30</Timeout>
</PaymentSettings>

For classes using this style (i.e. deriving from XmlDeserializeConfigSectionHandler) you can use validation attributes from the System.ComponentModel.DataAnnotations namespace as well as the DefaultValue attribute.

For both of these last two custom sections, you refer to them in your C# using the static "Current" property:

string url = CZ.PaymentSettings.Current.URL;

The .Net configuration system is quite sophisticated, try Google for more examples.

Special considerations for web applications

When you create a web application with Visual Studio it will create a Web.Debug.config and Web.Release.config file under your Web.config. These files are not needed anymore, you can just delete them.

Read the notes on setting up .gitignore so you don't accidentally disable your site.


Table Of Contents