#TIL: JsonConfig

I tweeted last week that I was starting to fall for JsonConfig, a configuration framework written by Timo Dorr for .NET. It’s a great utility that uses Json files to give you an object-based configuration (that’s right, NESTED VALUES!) and uses .net’s dynamic objects to provide it.

It was actually funny how it came up – I was thinking how I needed something slightly more powerful than ConfigurationManager.AppSettings on my project. At the same time a co-worker was asking me about ways to send configuration values from the server to the client, to which I suggested a hosted JSON file. In the back of my mind I thought “there’s got to be some way to combine the two” (well, I actually was thinking how I could write my own), and a quick google search turned up the JsonConfig repository on GitHub.

JsonConfig is a quick & simple library that uses JsonFX and .net’s dynamic feature to provide an object-based configuration to .NET applications. Your .conf JSON files can be placed as embedded resources in your libraries or as a .conf file in the application folder. Better yet, it supports a basic inheritance so you can specify defaults in your embedded files and overwrite or amend those settings with the application folder file.

It’s as simple as writing a json file:

1
2
3
4
5
6
7
8
9
{
  # This is a comment
  StoreOwner: "John Doe",
  Fruits: ["apple", "orange", "banana"],
  Address: {
      Street: 'Fake St',
      HouseNumber: 123
  }
}

and then accessing those settings through a static Config object:

1
2
3
4
5
6
Console.WriteLine(Config.Default.StoreOwner);
foreach(var fruit in Config.Default.Fruits)
{
  Console.WriteLine(fruit);
}
Console.WriteLine("{0} {1}", Config.Default.Address.HouseNumber, Config.Default.Address.Street);

My favourite feature is the fact that it’s defined as a dynamic object – you don’t have to create a “placeholder” object so you can access the settings in a strongly-typed manner, and you get the conciseness of an object definition rather than the flat key-value store you get with AppSettings.

Of course, you can override or merge settings in a separate .conf file (ideal for test or production deployment):

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
#embedded file
{
  StoreOwner: "John Doe",
  Fruits: ["apple", "orange"]
}
#.conf file
{
  StoreOwner: "Jane Doe",
  ProductionURL: "http://www.rtigger.com",
  Fruits: ["mango", "peach"]
}
#would result in
{
  StoreOwner: "Jane Doe",
  ProductionURL: "http://www.rtigger.com",
  Fruits: ["apple", "orange", "mango", "peach"]
}

As you can see, it does a type of smart merge – existing values are overridden, collections are combined, and new values are inserted. You can access each of those levels of configuration separately:

1
2
3
4
5
6
//embedded file
Config.Default.StoreOwner.Should().Be("John Doe")
//.conf file
Config.User.Fruits.Should().Contain("mango", "peach")
//merged result
Config.Global.StoreOwner.Should().Be("Jane Doe")

It also has some smart logic for absent config values – if you attempt to access a config setting that isn’t defined (regardless of the nesting) it will return a falsy-equivilent (false, null, or 0 depending on the type).

The only drawback I’ve run into for using JsonConfig is a lack of devops tools around manipulating .conf files (compared to those that exist for xml transforms / .config files), but that could be resolved easily enough. JsonCofing isn’t available on nuget, but you can download the source at the github page.

Comments