Home / Programming / Adding Dynamic Code to C# with IronRuby

Adding Dynamic Code to C# with IronRuby

Getting started with IronRuby is simple – just two quick steps:

1. Download and install IronRuby from http://ironruby.codeplex.com/. The latest version (as of this writing, 1.1.1) is compatable with .NET 4.0, but if you’re stuck in 2.0 or 3.5 then IronRuby version 1.0 will work fine in earlier versions of Visual Studio.

2. Once installed, create a new console application in visual studio, and add references to IronRuby, IronRuby.Libraries, Microsoft.Scripting.Core, and Microsoft.Scripting. The Microsoft.Scripting libraries are included with .NET 4.0 I believe, but if you install the IronRuby 1.0 release these will be found in the C:\Program Files\IronRuby 1.0\bin folder. In your console app, copy the following three lines:

var engine = IronRuby.Ruby.CreateEngine();
var result = engine.Execute("puts 'Hello, world!'", engine.CreateScope());
Console.WriteLine(result);

That’s it! You now have much* of the power and flexibility of the ruby language available to you in any .NET application. But, you ask, if you’re not a Ruby aficionado why would you want to do such a thing?

Assume you are developing a typical line of business application, one of the functions of which is to determine a discount for some customers at checkout. Business rules dictate that customers who joint the “Valued customer” program get offered a 10% discount at checkout. The prior coder on the project simply hard coded the rate into the program like so:

if (customer.ValuedCustomer)
price -= (price * 0.1f);

Any change to the discount required a rebuild and redeploy of the web site…. not a good solution. You propose storing the discount rate in a configuration value or database field that is easier to change, and initially everyone is very impressed with this solution. Until marketing decides they want to vary the discount based on the customer’s state. That requires a rebuild and redeploy…

What if instead of storing simply the discount rate in a configuration setting, you could store the entire discount function? With dynamic scripting and IronRuby this is easy. Use the scripting library’s SetVariable method to pass the customer record to a custom ruby function that calculates the discount. Whenever marketing decides to change business logic for the dicount, you can change the ruby function (stored in the database or config), and the app’s logic is updated without a recompile and redeploy. For example:

var customerRecord = new Customer () { ID = 10, FirstName = "John", LastName = "Smith", State = "CA", ValuedCustomer = true };
engine.Runtime.Globals.SetVariable("CUSTOMER", customerRecord);

var code =
@"def getDiscount(c)
if c.ValuedCustomer && c.State == 'CA'
return 0.1
else
return 0
end
end
getDiscount(CUSTOMER);
";
var discount = engine.Execute(code);