Recently we released version 1.0 of ConfigR - a popular .NET configuration library, that lets you configure your application via C# scripts (CSX).
This is also the last release requiring full .NET 4.5/Mono - the next version of ConfigR is going to be a netstandard.
Here’s a overview of the features that are there in 1.0!
What’s new π
Here is the overview of the new features.
New NuGet packages π
ConfigR is no longer coupled to C# scripting - instead it’s merely a configuration abstraction, and it’s just the abstraction code that is contained in the main ConfigR package.
This means that while scripting is the primary (or rather - at the moment - the only) way to use ConfigR, the ConfigR abstraction could be implemented against any configuration provider, allowing you to seamlessly merge multiple sources into a single configuration model (along with the scripting one).
To use ConfigR as a CSX/scripting configuration source, install the new ConfigR.Roslyn.CSharp package.
New Syntax π
ConfigR 1.0 introduces a new, simplified syntax of building up your configuration. Instead of calling Add
Additionally, changes are done to how you consume ConfigR in the host application, and that’s related to the fact that ConfigR can potentially have multiple configuration sources (as explained in the previous section).
Let’s have a look at some examples. First, the old syntax - no longer in use in ConfigR 1.0 - for some context.
// old CSX syntax
Add("Count", 123);
Add("Link", new Uri("https://github.com/config-r/config-r"));
// app
void Main(string[] args)
{
var count = Config.Global.Get<int>("Count"); // it's a System.Int32!
var link = Config.Global.Get<Uri>("Link"); // it's a System.Uri!
}
In ConfigR 1.0.0 you can assign the values to a global object “Config” directly:
//new CSX syntax
Config.Link = new Uri("https://github.com/config-r/config-r");
Config.Count = 123;
Now, there are a few ways to retrieve the values. Loading values must be set up upfront with the correct loader (at the moment it would always be Roslyn scripting) and is an async operation.
The most elegant approach to load configuration would be to use a POCO. For example:
class MyConfig
{
public int Count {get; set;}
public Uri Link {get; set;}
}
// app
void Main(string[] args)
{
// set up ConfigR to use Roslyn CSX scripting and load the config into a POCO
var config = new Config().UseRoslynCSharpLoader().Load<MyConfig>().GetAwaiter().GetResult();
var count = config.Count; // it's a System.Int32!
var link = config.Link; // it's a System.Uri!
}
Another approach is to use dynamic loading:
// app
void Main(string[] args)
{
// set up ConfigR to use Roslyn CSX scripting and load the config into dynamic object
var config = new Config().UseRoslynCSharpLoader().LoadDynamic().GetAwaiter().GetResult();
var count = config.Count; // it's a dynamic with System.Int32 under the hood
var link = config.Link; // it's a dynamic with System.Uri under the hood
}
Finally it’s also possible to load into an IDictionary<string, object>:
// app
void Main(string[] args)
{
// set up ConfigR to use Roslyn CSX scripting and load the config into a dictionary
var config = new Config().UseRoslynCSharpLoader().LoadDictionary().GetAwaiter().GetResult();
var count = config["Count"]; // it's an object with System.Int32 under the hood
var link = config["Link"]; // it's an object with System.Uri under the hood
}
Implicit reference back to the main project π
The configuration script now has an implicit back reference to the main application, meaning that from within the script you can easily access all of the public types defined in your application.
In the past, in order to reference host application types you had to manually use #r directive.
#r "ConfigRDemo.exe"
using ConfigRDemo;
// DataTarget enum comes from the host app
Add("DataTarget", DataTarget.Production);
Similar code in ConfigR 1.0 is less verbose:
using ConfigRDemo;
Config.DataTarget = DataTarget.Production;
Less dependencies and Mono compatibility π
ConfigR is now leaner, as it doesn’t depend on scriptcs anymore - instead it’s completely standalone (the main ConfigR abstraction) or only built directly on Roslyn (the CSX COnfigR loader).
This also means it’s also Mono compatible right now, and paves an easy way to a .NET Core port in the next release. Oh, and the dreaded JSON.NET dependency was dropped too.
Support for loading remote scripts π
#load directives now supports HTTP based references. Thus you can distribute and delegate your configuration to remote services.
The example is shown below.
// foo.csx hosted remotely
Config.Link = new Uri("https://github.com/config-r/config-r");
// CSX embedded into the app
#load "http://localhost/foo.csx"
Config.Count = 123;
Other bug fixes and small improvements π
A bunch of other bug fixes an improvements were done. For example, ConfigR supports in-memory assemblies, meaning you can now use it to configure applications which only exist in memory and are never flushed into a physical assembly on disk.
Oh and there is a new logo π
If you wanna help building ConfigR (next step - netstandard!) - stop by Github!
Finally, huge thanks to Adam who has been the mastermind behind all this.