Intro to IronRuby/DLR Scripting in C# Silverlight 4 Application
I’ve been working lately on figuring out how to add DLR scripting support to a Silverlight 4 application I’ve been working on. The idea is to give it a plugin style architecture, with the plugins being written in a DLR language; currently focusing on IronRuby. I originally searched how to do this, but couldn’t find any recent articles that discuss Silverlight 4. Also, most articles out don’t target Silverlight and more of them discuss IronPython and not IronRuby, even though the DLR stuff is the same regardless of DLR language used.
So, I thought I’d share what I’m learning about adding IronRuby scripting to Silverlight 4 applications. I’m also focusing on C# as the host language, but the .NET object and methods used will be the same from VB.NET.
Older Articles for Reference <ul> <li>Adding scripting to a C# Silverlight app </li> <li>Scripting C# Silverlight apps with IronPython </li> <li>IronRuby script engine in C# </li> <li>Extending your C# application with IronPython </li> <li>Getting Started with IronRuby and SIlverlight </li> </ul> ## What to download?
Since I am talking about using Silverlight 4, you will need Visual Studio 2010 installed.
You will need to have the following installed: <ul> <li>Silverlight 4 Tools for Visual Studio 2010 </li> </ul>
Also, download the following and extract, as it will be used later: <ul> <li>IronRuby 1.1 (.NET 4.0 ZIP & Silverlight 4) </li> </ul> ## Add Assembly References to Silverlight Project
Either create a new Silverlight 4 project or use an existing one, then add the references to the following assemblies located within the “silverlight/bin” folder of the IronRuby 1.1 archive previously downloaded. <ul> <li>IronRuby.dll </li> <li>IronRuby.Libraries.dll </li> <li>IronRuby.Libraries.Yaml.dll </li> <li>Microsoft.Dynamic.dll </li> <li>Microsoft.Scripting.Debugging.dll </li> <li>Microsoft.Scripting.dll </li> <li>Microsoft.Scripting.Silverlight.dll </li> <li>System.Numerics.dll </li> </ul>
If your using a C# project, then you will also need to Add Reference to Microsoft.CSharp namespace. ## Execute IronRuby Code from C#
It is actually very simple to use the ScriptEngine class to execute DLR code from within C# (or any other .NET language.)
Here’s a small example that show how to use ScriptEngine to execute a small piece of IronRuby code: <pre class="csharpcode">// Create instance of the IronRuby ScriptEngine
ScriptEngine engine = Ruby.CreateEngine();
// some IronRuby code to execute // this just adds 2 plus 2 var code = “2 + 2”;
// Execute the code and catch the result // in a variable var result = engine.Execute(code);
// After execution “result” should contain // the value “4”</pre>
As you can see, it really is only 2 lines of code required to execute a piece of IronRuby (or other DLR language) code.
Use Global Variables to Grant Access Within Your Application
The ScirptEngine class allows you to set global variables from .NET code to allow the DLR language (in this case IronRuby) access to them.
Here’s an example of creating a global variable “MainPage” that is a reference to the object that is executing the code. The MainPage object also implements a method named “SetTitleText” that the IronRuby code will call.
public partial class MainPage : UserControl { public void SetTitleText(string t) { this.txtTitle.Text = t; } void MainPage_Loaded(object sender, RoutedEventArgs e) { ScriptEngine engine = Ruby.CreateEngine(); // Set global variable for access to this Page instance // The Ruby code will only be able to access the "MainPage" // global variable engine.Runtime.Globals.SetVariable("MainPage", this); // Use Ruby to set the text displayed in a TextBlock using a method // exposed by this Page object string code = "MainPage.SetTitleText(\"Hello from IronRuby!\")"; engine.Execute(code); } }
Using this you can grant the DLR script access to any objects or methods within your application.
Return Object Instance from IronRuby and Execute a Method from C#
Here’s another code example of executing IronRuby code from C#. This time the IronRuby code is creating an instance of an object and returning that object so that C# can call one of its methods.
ScriptEngine engine = Ruby.CreateEngine(); // Execute IronRuby code that creates an // instance of a class dynamic obj = engine.Execute(@" class MyObject def add(a, b) a + b end end MyObject.new "); // call the "add" method of the IronRuby object var i = obj.add(1, 2); // Display the result of the IronRuby method to // the user HtmlPage.Window.Alert("i = " + i);
Conclusion
The examples shown here may seem really simple and not to offer much, but this is just the basics of what can allow you to add a ton of power to your applications. Being able to easily script certain pieces of your application without the need to recompile and redeploy the solution can drastically increase the speed at which certain application changes, such as business logic, can be implemented. This also allows for a much more modular plug-in model to be developed in to the application; which is what I’m looking to do.