Saturday, January 7, 2012

Using App.Config in IronPython

I love python very much, and as you probably already noticed, I love C# as well. I already have many libraries and utilities developed in those languages, and for me, the ability to reuse code between those languages, is a must.
So I came to know IronPython, which is a complete Python implementation for the .NET platform, using the DLR. For most of the time, the integration between the two is a breeze. All you have to do is "clr.AddReference" your .NET assemblies, and you're good to go.

Unfortunately, with more complex projects, there are some caveats. Most notably is the missing ability to load app.config (or web.config, or any other .config) files from IronPython. Without diving too much into details, the reason is the way AppDomain works in .NET. It is looking for [assembly name].config file when one is requested using the ConfigurationManager. Since IronPython code is invoked with ipy.exe, the configuration file must be called ipy.exe.config. I suppose the same goes with IronRuby as well. This is a serious limitation.

Thanks to Tom E. Stephans for providing this awesome proxy for the ConfigurationManager. Basically, his code injects some logic to the inner workings of the ConfigurationManager, that allows us to specify which config file to be loaded. This config file will be seamlessly loaded by the ConfigurationManager when needed.
Unfortunately, Tom's code doesn't exactly compile. Probably due to some copy-paste issues he had when publishing it. So I did some minor modifications, and removed the part of the code responsible for loading custom configuration sections and uploaded it to Bitbucket, so everyone can use it. The code is available here, along with a sample usage python script.

Few things to keep in mind regarding my code:

  • It was compiled using Mono 2.10 like this: mcs ConfigurationProxy.cs -t:library -r:System.Configuration
  • It was tested both under Mono and under MS .NET framework 4.0.
  • There's a sample config file called blogsample.config which contains a demo connection string. This configuration file is loaded in test.py and the connection string is printed.
  • Just like the ".ConnectionStrings" collection is accessed, one can access the ".AppSettings" collection.
  • Since the injection is done to the ConfigurationManager, implicit usage attempts will also work. For instance, the SubSonic ORM which requires a connection string, will work seamlessly.
Once again, kudos to Tom for his great work. I hope you will find my corrections and sample useful.