Tari has a neat post over at his blog about treating configuration as code with Pythonís import hooks. I thought the way he handled it was really neat--basically, he loads in an INI file, and it creates a dynamic object with properties equal to the INI file. So, his example was a file such as:

Well, I thought this was really cool and wanted to do something similar in C#. I found a neat class called ExpandoObject that would allow for this sort of thing to C#. So, for example, given the above INI file you could do:

And it would output "meow". Because of the way the objects work, it's also trivial to iterate over the properties and such. Here's a screen shot showing more advanced output with a slightly larger INI file:
The code to do that is very simple:

// Because we're using ExpandoObjects, which implement IDictionary<string, object>,
// we can also iterate over the collection. Each item in the config is another ExpandoObject
// meaning we can iterate over that as well.
Console.WriteLine("Iterating over properties:");
foreach (var prop in ((IDictionary<string, object>)config)) {
Console.WriteLine("A {0}:", prop.Key);
foreach (var key in ((IDictionary<string, object>)prop.Value)) {
Console.WriteLine("\t{0}={1}", key.Key, key.Value);
}
}

Neat to see that my experiment inspired something, but it seems like your solution misses some of the things that make the Python version particularly nice, such as ease of reloading: in the Python version, a simple reload(foo) (or impl.reload(foo) on Python 3.x) will reload the config and update the name binding in all active scopes, which is quite handy.

I noticed that in your blog post, though I didn't quite understand the impetus behind it--how often is one reloading a config file programmatically like that? I can see it's use a a REPL and such, but I'm not 100% sure about workflows for it. That being said, I can try adding that and see how it goes.

Quote:

ExpandoObject is a silly name, but a useful thing, apparently.

Heh, that's exactly what I thought! I can't help but wonder how that name came about; I think it has something to do with someone not being able to pronounce "expandable" when they were describing the functionality to the person who made it.

The config admittedly doesn't get reloaded often. But for long-running programs, it becomes very easy to reload the config from disk on-demand. Could even set something (very simple) up to watch the backing file and do the reload on modification (though that seems like a fragile way to do it).

Ooh, that definitely makes sense--I wasn't even thinking about long-running programs. C# has some file-monitoring stuff, too, so it would be pretty simple for a user to set something up like that if they wanted.

So you can see the real work is just Config.ReloadIni(config, "Config2.ini"); which is pretty simple to do. Download in the same place:
http://merthsoft.com/DynamicConfig.zip
Code's there if anyone wants to see how I managed it.

Two and a half year update! I've made some changes to it so that now, with some configuration passed in when reading, you can make it so it returns null if you try to access a member that does exist, instead of throwing an exception. I also made it so that you can have the members be case-insensitive.
https://bitbucket.org/merthsoft/dynamicconfig

Have your own thoughts to add to this or any other topic? Want to ask a question, offer a suggestion, share your own programs and projects, upload a file to the file archives, get help with calculator and computer programming, or simply chat with like-minded coders and tech and calculator enthusiasts via the site-wide AJAX SAX widget? Registration for a free Cemetech account only takes a minute.