Introduction to ConfigR, the solution to your application configuration problems.

Are you still using XML files to store your application settings? Are you still placing your website properties in the web.config? Have you developed a nifty, cool, special library to manage XML files full of configuration properties? Do you, like me, find XML extremelly annoying even with all the new APIs such as LINQToXml? Sureley there must be something better out there?

Well look no more, because I have the solution! Let me introduce you to ConfigR, the excellent little tool written by Adam Ralph. What is ConfigR you may ask? As Adam elegantly pitches it:

ConfigR allows you to write your config in C# instead of XML - that's really all there is to it. From that point on you can use your imagination to go wild in what you do in that C#.

That's all there is to it. ConfigR is painfully simple yet surprisingly powerful at what it can do for you (and your sanity). No more need to use web.config or app.config files just to host your setting variables. Let's see a few simple ConfigR examples.

1. Starting out with ConfigR

Start by creating a console app and Visual Studio. Go ahead and name it ConfigRTest (yes, I have a vivid imagination when it comes to naming things :) ). With the solution in place, download ConfigR from NuGet. For the hardcore/console-lovers type the following in the NuGet console:

Or you can go down the NuGet Package Manager and browse to it. In any case, your solution packages should now look like this:

You may have noticed that a number of additional packages were installed in your solution. Interestingly, ScriptCs is one of them. You guessed it right, ConfigR relies on ScriptCs to do the heavy pulling behind the scenes. I promise to do a post on ScriptCs soon, but for now that's all you have to know.

Next, we need to add a .csx file in our console app. The easiest way to do this is to create a text file in the project root and then rename it. You need to ensure that the .csx file has the same name as your console executable. In this example, the new file should be ConfigRTest.exe.csx. Make sure that the file properties are set to Copy Always for the Copy to Output Directory option.

With the hard part finished (yes, really, that's all to it), we can start adding configuration properties to the file, as per the example below:

Add("Name", "ChristosMatskas");
Add("Age", 18);
Add("IsThisYourAge", false);
Add("MyRealAge", 35);
Add("CheckTheSourceCode", new Uri("https://github.com/config-r/config-r"));

Now, in your console's Main() method, call these variables like so:

using System;
using ConfigR;

namespace ConfigRTest
{
    class Program
    {
        public static void Main(string[] args)
        {
            var name = Config.Global.Get<string>("Name");
            var age = Config.Global.Get<int>("Age");
            var forReal = Config.Global.Get<bool>("IsThisYourAge");
            var actualAge = Config.Global.Get<int>("MyRealAge");
            var getMore = Config.Global.Get<Uri>("CheckTheSourceCode");
            Console.WriteLine("Name: {0}", name);
            Console.WriteLine("Age: {0}", age);
            Console.WriteLine("For Real?: {0}", forReal);
            Console.WriteLine("Actual Age: {0}", actualAge);
            Console.WriteLine("Where can I get more?: {0}", getMore);
            Console.ReadLine();
        }
    }
}

If you run the console app, the outcome should be similar to this:

2. Show me more

The fact that ConfigR allows us to use any valid C# in our config file means that we can even store more complex items! So, how about a class? Let's do it. First, add a class to the solution and give it an original name: Foo. Add a string property Bar and a DateTime property BarTime. That's enough, I'm tired.

namespace ConfigRTest
{
    public class Foo
    {
        public string Bar { get; set; }
        public DateTime BarDateTime { get; set; }
    }
}

Now, go ahead and add a property of type Foo in the config file:

#r "ConfigRTest.exe"
using ConfigRTest;

Add("Name", "ChristosMatskas");
Add("Age", 18);
Add("IsThisYourAge", false);
Add("MyRealAge", 35);
Add("CheckTheSourceCode", new Uri("https://github.com/config-r/config-r"));
Add("Foo", new Foo {Bar="I am a Bar", BarDateTime = DateTime.Now});

Note the namespace import on the first 2 lines: #r "ConfigRTest.exe" and using ConfigRTest;. This is required when using complex types. Obviously you will need to add all necessary namespaces if you are importing objects from multiple projects.

3. Other interesting features

It quickly becomes apparent that ConfigR is a very powerful little tool. You can add and edit properties in your code and it is very easy to use. you can use custom locations and names for the .csx files. ConfigR allows you to have multiple .csx files and load them programatically only when necessary. You can even call .csx files from within other .csx files creating a virtual configuration hierarchy.

I found that there are some minor disadvantages(?) with using ConfigR over the standard app/web.config:

  • you cannot use transformations (but then again you don't need to)
  • you cannot use Azure Website configuration settings to pass values to your web.config.

However, I find these two issues platform specific and there is nothing stoping you combing both tehcnologies to better match your needs. No tool is perfect and no one library is the solution to every problem but this is definitely one that I can easily see my self using on new projects.

In this post, I only scratched the surface of ConfigR and I would welcome you to visit the GitHub page and have a look at the samples to find out more. XML can now rest in peace, free of "Enterprise" abuse.