Sponsor: Do you build complex software systems? See how NServiceBus makes it easier to design, build, and manage software systems that use message queues to achieve loose coupling. Get started for free.
I stumbled upon ConfigR a several months ago on twitter from Glenn Block. It uses ScriptCS (and Roslyn) and was developed by Adam Ralph. I finally got around to take it for a test drive on a side project. It’s really a simple tool that I’ve been waiting for.Why ConfigR?
The purpose of ConfigR is pretty straight forward. It allows you to write C# code to define configuration settings which you would normally place in a the appSettings section of a web.config/app.config. If you have used the appSettings at all, you probably wished they could be typed instead of always having to be strings. From Adam Ralph, the creator of ConfigRConfigR 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#.
Install via NuGet
Make sure your project is set to be using .NET 4.5 or greater You need to get ConfigR into your project. Install via the Package Manager in Visual Studio.PM> Install-Package ConfigROr if you prefer via the NuGet UI
Web Application
This portion has been updated to reflect the proper way of sing ConfigR with a web application. Thanks to creator Adam Ralph for clarification below in the comments.The default naming convention ConfigR uses to automatically load your configuration file is to look for a file in your output directly named Web.csx.
- Create a new file in your project named Web.csx
- Make sure the Copy to Output Directory is set to Do not copy.
This is different than a console app in which you do want to copy to output dir. In a web application, we want the Web.csx in the same location as you would normally see the web.config.I’m going to create two simple configuration settings in our new Web.csx file As you can expect the Add method is adding items into the ConfigR global configuraiton. The two configuration settings I’ve created are of different types: boolean and string. Now in code when we need to access these configuration settings, it couldn’t be any easier.
Thanks for the great blog post!
With regard to using your own types for web apps, I’ve just updated the samples to show how to do this, see https://github.com/config-r/config-r-samples/tree/41f2958bc7415df831c02e5cc5b68c464e77dcf0/src/ConfigR.Samples.WebApplication
The key points are:
1. Web.csx must have ‘Copy to Output Directory’ set to ‘Do not copy’.
2. The assembly must be referenced in the ‘bin/’ subfolder
The ‘Copy to Output Directory’ property should always be set to ‘Do not copy’ when using ConfigR in a web app since ConfigR looks for Web.csx in the same location as Web.config, which is the project root folder rather than ‘bin/’. When you set the property to ‘Copy always’ in a web app, the copy in ‘bin/’ is redundant since it is not used. I’m sorry this wasn’t made clear in the documentation. In fact, someone else stumbled upon this same problem just last week. I’ve updated the quick start accordingly – https://github.com/config-r/config-r/wiki/Quickstart. It would be good if you could correct this in the blog post.
Thanks again!
Thanks Adam! This worked like a charm. I’ve updated this post.
Looks good!
Complex Types? IMO, he needs to change “Add” to “Add”, then supply any type you care to serialize!
You can already supply any type. There is no serialization taking place. The config script executes in-process and whatever objects it adds are they same references that are used in the app.
The problem Derek had with this was simply due to an incorrect assumption about the location of the config script on disk at runtime (see my comment).
Pingback: The Morning Brew - Chris Alcock » The Morning Brew #1868
Why not just use project settings and not have to use any magic strings or know the type of each setting? This seems like a lot more work for something that’s already been done.
Settings files are all based on magic strings, it’s just that there is code generated to wrap them. You could equally write similar code to wrap the magic strings you use when using ConfigR.
Also bear in mind that settings files rely on serialization of string values from app.config and thus only a limited number of types can be used. With ConfigR there is no serialization taking place so you have the entire type system at your disposal.
However, the true value of ConfigR is being able to defer all configuration decisions until runtime, and a complete decoupling of configuration strategy from application code, i.e. the config file can do ‘anything’. With settings files you are essentially still limited to static key value pairs.
Looks nice, but what about config transformations (like for web.config or app.config with SlowCheetah)? Is there any way to do that with ConfigR?
Config transformations are a solution for making configuration decisions at build time. ConfigR allows you to defer all configuration decisions until runtime. In short, you just don’t need config transformations when you use ConfigR.
Actually you do need it, because Debug/Test/Release configurations won’t go anywhere (especially when using CI). Inside the code, of course, I could use
#ifdef DEBUG
but I can’t use it inside ConfigR code, right? (because ConfigR will be compiled on the fly later?).
Sorry, you’re correct. I’ve not had to use separate debug/release configs for a long time and I forgot the purpose of config transformations ;-).
I even showed an example of how to do it here https://github.com/adamralph/config-r-samples/blob/41f2958bc7415df831c02e5cc5b68c464e77dcf0/src/ConfigR.Samples.WebApplication/Global.asax.cs#L22-L26
Instead of loading a separate file, another way to do this would be to set a variable in the app, and let the single default Web.csx switch on that value.
Yea, I think I got the idea, you have to use ifdef macro to set some global variable inside the application and then use it from the ConfigR for selecting proper configuration. Sounds pretty easy and usable 🙂 Thank you!