• Stars
    star
    202
  • Rank 193,691 (Top 4 %)
  • Language
    C#
  • License
    MIT License
  • Created over 12 years ago
  • Updated about 9 years ago

Reviews

There are no reviews yet. Be the first to send feedback to the community and the maintainers!

Repository Details

simple configuration library using JSON and C# 4.0 dynamic feature

JsonConfig README

About

JsonConfig is a simple to use configuration library, allowing JSON based config files for your C#/.NET application instead of cumbersome web.config/application.config xml files.

It is based on JsonFX and C# 4.0 dynamic feature. Allows putting your programs config file into .json files, where a default config can be embedded as a resource or put in the (web-)application folder. Configuration can be accessed via dynamic types, no custom classes or any other stub code is necessary.

JsonConfig brings support for config inheritance, meaning a set of configuration files can be used to have a single, scoped configuration at runtime which is a merged version of all provided configuration files.

Example

Since my lack of skills in writing good examples into a documentation file, it is best to take a look at the examples/ folder with a complete commented .sln which will give you a better understanding (TODO).

Getting started

Usually the developer wants a default configuration that is used when no configuration by the user is present whatsoever. Often, this configuration is just hardcoded default values within the code. With JsonConfig there is no need for hardcoding, we simply create a default.conf file and embedd it as a resource.

Let's create a sample default.conf for a hypothetical grocery store:

# Lines beginning with # are skipped when the JSON is parsed, so we can
# put comments into our JSON configuration files
{
	StoreOwner : "John Doe",
	
	# List of items that we sell
	Fruits: [ "apple", "banana", "pear" ]
}

JsonConfig automatically scan's all assemblies for the presence of a default.conf file, so we do not have to add any boilerplate code and can directly dive in:

// exmaple code using our configuration file
using JsonConfig;
[...]
public void PrintInfo () {
	var storeOwner = Config.Default.StoreOwner;

	Console.WriteLine ("Hi there, my name is {0}!", storeOwner);

	foreach (var fruit in Config.Default.Fruits)
		Console.WriteLine (fruit);

}

However, the developer wants the user to make his own configuration file. JsonConfig automatically scans for a settings.conf file in the root path of the application.

# sample settings.conf
{
	Fruits: [ "melon", "peach" ]	
}

The settings.conf and the default.conf are then merged in a clever way and provided via the Global configuration.

public void PrintInfo () {
	// will result in apple, banana, pear 
	foreach (var fruit in Config.Default.Fruits)
		Console.WriteLine (fruit);

	// will result in melon, peach
	foreach (var fruit in Config.User.Fruits)
		Console.WriteLine (fruit);

	// access the Global scope, which is a merge of Default
	// and User configuration
	// will result in apple, banana, pear, melon, peach
	foreach (var fruit in Config.Global.Fruits)
		Console.WriteLine (fruit);

}

Nesting objects

We are not bound to any hierarchies, any valid JSON is a valid configuration object. Take for example a hypothetical webserver configuration:

{
	ListenPorts: [ 80, 443 ],
	EnableCaching : true,
	ServerProgramName: "Hypothetical WebServer 1.0",

	Websites: [
		{
			Path: "/srv/www/example/",
			Domain: "example.com",
			Contact: "[email protected]"	
		},
		{
			Path: "/srv/www/somedomain/",
			Domain: "somedomain.com",
			Contact: "[email protected]"
		}
	]
}	

Above configuration could be accessed via:

using JsonConfig;
[...]

public void StartWebserver () {
	// access via Config.Global
	string serverName = Config.Global.ServerProgramName;
	bool caching = Config.Global.EnableCaching;
	int[] listenPorts = Config.Global.ListenPorts;

	foreach (dynamic website in Config.Global.Websites) {
		StartNewVhost (website.Path, website.Domain, website.Contact);
	}
}

"Magic" prevention of null pointer exceptions

Choosing reasonable default values is only a matter of supplying a good default.conf. But using some C# 4.0 dynamic "magic", non-existant configuration values will not throw a NullPointer exception:

// we are lazy and do not want to give default values for configuration
// objects, but just want them to be false

// there is no need to have LoadedModules OR HttpServer in your
// default.conf, if missing this will just evaluate to false
if (Config.Global.LoadedModules.HttpServer) {
	// start HttpServer
}

// more drastic example, its safe to write
if (Config.Global.nonexistant.field.that.never.will.be.given) {
	// this will never be run unless you create that structure in your
	// config files
}

// when the configuration value is cast to string, it will be null if not
// given
if (string.IsNullOrEmpty (Config.Global.some.nonexistant.nested.field)) {
	// will most likely be run all the times
}

The "magic" allows you to cast a not-yet existing field to common types, which will then have empty or default values:

foreach (string name in Config.Global.NonExistantField as string[]) {
	// instead of being cast to null, if a non-existing field is cast to string[] it
	// will just be an empty array: string[]Β {Β }
	Console.WriteLine (name);
}

// works for nullable types, too. Nullable types will
// cast to null if not exsisting in the config.
var processFiles = (bool?) Config.Global.ProcessFiles;
if (processFiles != null) {
	// will only be run if ProcessFiles is present in the config
	DoSomethingWithDirectory (processFiles);
}

Bitdeli Badge

More Repositories

1

mdwiki

CMS/Wiki system using Javascript for 100% client side single page application using Markdown.
JavaScript
3,109
star
2

reactive-state

Redux-clone build with strict typing and RxJS down to its core. Wrist-friendly, no boilerplate or endless switch statements
TypeScript
138
star
3

Rainy

Simple Tomboy/Tomdroid cloud/syncing server. Written in C# with AngularJS web frontend. Supports SQLite & Postgres Backends.
JavaScript
87
star
4

mdwiki-seed

Basic template file layout to start with MDwiki - see http://mdwiki.info
26
star
5

tcp_probe_fixed

Bugfixed & modified version of tcp_probe.c linux kernel module to monitor congestion/flow control of tcp connections
C
25
star
6

mdwiki-examples

A collection of example wesbites created with MDwiki
23
star
7

redux-pattern-with-rx

Basic Redux implementation in RxJS. For educational and production use
TypeScript
14
star
8

reactive-state-react-example

A full React Counter/Todo application using reactive-state as a Container plus RxJS instead of Redux
TypeScript
6
star
9

genbanking

A simple framework for common banking tasks with webservice access through SOAP and JSON. Currently support german Bankaccount via HBCI
C#
5
star
10

PortableIoC

Single .cs file IoC container for .NET/PCL. Fork from portableioc.codeplex.com
C#
4
star
11

banshee-osx

My local mirror for banshee on OS X to work during my GSoC
C#
2
star
12

tomboy-sync-example

Example of how to use Tomboy-library to sync with a a WebSync Server such as Rainy
C#
2
star
13

MarkdownSharp

Fork from the google-code hosted MarkdownSharp at http://code.google.com/p/markdownsharp/
C#
2
star
14

aqbankingNET

A common language runtime (CLR) wrapper for aqbanking that allows usage of the C/C++ aqbanking library from C# and other .NET languages using mono on Linux/UNIX and possible windows.
2
star
15

autobahn-ts

TypeScript fork/port of the original autobahnJS library
JavaScript
1
star
16

jquery-lazy-gist

a jQuery plugin that will lazy load your gists.
JavaScript
1
star
17

coffeeloader

A node.js based http server that dynamically compiles and conditionally assembles Coffeescript and Javascript using configured profiles
CoffeeScript
1
star