Re.Mark

My Life As A Blog

Configuration with IronPython

with one comment

Configuring applications in code seems like a good idea.  Configuring them in code written in a dynamic language seems even better.  Let’s look at a simple example with IronPython.

Creating a simple application

To start off, create a simple console solution called ConfiguredConsole.  Then create a class called Configuration, which looks like this:


public class Configuration
{
    public string Text;
    public int Count;
}

Next, let’s create a simple application that uses that configuration class.  For now, we’ll configure the application in-line.  Here’s the code for the Program class:


static void Main(string[] args)
{
    try
    {
        Configuration configuration = ConfigureInLine();

        for (int i = 0; i < configuration.Count; i++)
        {
            Console.WriteLine(configuration.Text);
        }
    }
    catch (Exception ex)
    {
        Console.WriteLine(ex);
    }

    Console.WriteLine("Press any key to exit...");
    Console.ReadKey();

}

private static Configuration ConfigureInLine()
{
    Configuration configuration = new Configuration();
    configuration.Text = "Hello";
    configuration.Count = 2;
    return configuration;
}

Simple enough and runs as you’d expect:

image 

Using traditional configuration

Before we use IronPython for the configuration let’s modify the application to use traditional configuration.  Firstly, add an App.Config file:


<?xml version="1.0" encoding="utf-8" ?>
<configuration>
  <appSettings>
    <add key="text" value="Hello from app.config"/>
    <add key="count" value="3"/>
  </appSettings>
</configuration>

Next, add a function to configure the application.


private static Configuration ConfigureFromFile()
{
    AppSettingsReader reader = new AppSettingsReader();
    Configuration configuration = new Configuration();
    configuration.Text = (string)reader.GetValue("text", typeof(string));
    configuration.Count = (int)reader.GetValue("count", typeof(int));
    return configuration;
}

OK, now we can comment out the line that called the ConfigureInLine method and add one calling our ConfigureFromFile method:


//Configuration configuration = ConfigureInLine();
Configuration configuration = ConfigureFromFile();

Once again, running the application does what we’d expect:

image

Dynamic configuration

Time to get dynamic.  Add a file called Configuration.py – remember to set the Copy To Output Directory property to Copy if newer or Copy always.  It looks like this:


configuration.Text = "Hello from IronPython"
configuration.Count = 4

It’s a very simple bit of Python that configures the application.  Now we just need a function that runs the Python code:


private static Configuration ConfigureFromIronPython()
{
    Configuration configuration = new Configuration();

    ScriptScope scope;
    ScriptEngine engine;
    engine = Python.CreateEngine();
    scope = engine.CreateScope();
    scope.SetVariable("configuration", configuration);
    string code = File.ReadAllText("Configuration.py");
    ScriptSource source = engine.CreateScriptSourceFromString(code, Microsoft.Scripting.SourceCodeKind.Statements);
    source.Execute(scope);

    return configuration;
}

In addition to creating the hosting environment, this function passes a copy of the Configuration instance so that it can be shared between the application and IronPython.

Finally, comment out the line that called the ConfigureFromFile method with add one calling the ConfigureFromPython method:


//Configuration configuration = ConfigureFromFile();
Configuration configuration = ConfigureFromIronPython();

Run it and we can see that Python has configured the application.

image

What next?

I’ve kept this example as simple as possible to show the principles.  The advantages of using Python code (it would be simple to use IronRuby, too) are that it’s simpler to write, testable, more powerful and doesn’t need pre-compiling.  And it could do much more than set a couple of properties.  In C# 4.0 the dynamic keyword would allow the Configuration class (and classes like it) to be dynamic, so that the properties and methods could be referenced at runtime without having to be declared ahead of time.

Advertisements

Written by remark

September 14, 2009 at 4:37 pm

One Response

Subscribe to comments with RSS.

  1. this is a great article, very clear explanation. thanks for sharing. I have a book on IronPython on order and I’m looking forward to giving it a try.

    Mark

    October 9, 2009 at 2:09 pm


Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

%d bloggers like this: