Using .NET to make your Application Scriptable

Page 2 of 5
  1. Introduction
  2. The Object Model, Host Application & Script Editor
  3. Dynamic Compilation
  4. Analysing the Compile Results
  5. Finishing Off

The Object Model, Host Application & Script Editor

The Object Model

This part is just the same as writing for plugin-based applications. The first step is to create a shared dll which is referenced by the host application and contains the interfaces needed to be known by both that and the script. My imagination being what it is, for this article we'll make a simple host application that has four buttons on it and calls methods in a script when each button is clicked. It will make available to the script a UI control and a method to show a message box.

Here are the interfaces:

[VB]
Public Interface IScript
    Sub Initialize(ByVal Host As IHost)
    Sub Method1()
    Sub Method2()
    Sub Method3()
    Sub Method4()
End Interface
Public Interface IHost
    ReadOnly Property TextBox() As System.Windows.Forms.TextBox
    Sub ShowMessage(ByVal Message As String)
End Interface

[C#]
using System;
namespace Interfaces
{
    public interface IScript
    {
        void Initialize(IHost Host);
        void Method1();
        void Method2();
        void Method3();
        void Method4();
    }
    public interface IHost
    {
        System.Windows.Forms.TextBox TextBox { get; }
        void ShowMessage(string Message);
    }
}

The Host Application

Before we get in to how we're going to edit and compile the script, let's design the simple host application. All we want is a form with a textbox and four buttons on it. We will also want two variables scoped to the whole form, one to store the current script source and one of type IScript that we'll use to call the compiled script's methods. The form itself will implement IHost for simplicity. We also want another button that we'll use to show the script editing dialog.

[VB]
Public Class Form1
    Inherits System.Windows.Forms.Form
    Implements Interfaces.IHost
    'Designer stuff removed for clarity
    Private ScriptSource As String = ""
    Private Script As Interfaces.IScript = Nothing
    Public ReadOnly Property TextBox() As System.Windows.Forms.TextBox Implements _
    Interfaces.IHost.TextBox
        Get
            Return txtOutput
        End Get
    End Property
    Public Sub ShowMessage(ByVal Message As String) Implements _
    Interfaces.IHost.ShowMessage
        MessageBox.Show(Message)
    End Sub
    Private Sub btnFunction1_Click(ByVal sender As System.Object, ByVal e As _
    System.EventArgs) Handles btnFunction1.Click
        If Not Script Is Nothing Then Script.Method1()
    End Sub
    Private Sub btnFunction2_Click(ByVal sender As System.Object, ByVal e As _
    System.EventArgs) Handles btnFunction2.Click
        If Not Script Is Nothing Then Script.Method2()
    End Sub
    Private Sub btnFunction3_Click(ByVal sender As System.Object, ByVal e As _
    System.EventArgs) Handles btnFunction3.Click
        If Not Script Is Nothing Then Script.Method3()
    End Sub
    Private Sub btnFunction4_Click(ByVal sender As System.Object, ByVal e As _
    System.EventArgs) Handles btnFunction4.Click
        If Not Script Is Nothing Then Script.Method4()
    End Sub
    Private Sub btnEditScript_Click(ByVal sender As System.Object, ByVal e As _
    System.EventArgs) Handles btnEditScript.Click
        'TODO
    End Sub
End Class

[C#]
public class Form1 : System.Windows.Forms.Form, Interfaces.IHost
{
    // Designer stuff removed for clarity
   
    string ScriptSource = "";
    Interfaces.IScript Script = null;
    public System.Windows.Forms.TextBox TextBox
    {
        get
        {
            return txtOutput;
        }
    }
    public void ShowMessage(string Message)
    {
        MessageBox.Show(Message);
    }
    private void btnFunction1_Click(object sender, System.EventArgs e)
    {
        if (Script != null) Script.Method1();
    }
    private void btnFunction2_Click(object sender, System.EventArgs e)
    {
        if (Script != null) Script.Method2();
    }
    private void btnFunction3_Click(object sender, System.EventArgs e)
    {
        if (Script != null) Script.Method3();
    }
    private void btnFunction4_Click(object sender, System.EventArgs e)
    {
        if (Script != null) Script.Method4();
    }
    private void btnEditScript_Click(object sender, System.EventArgs e)
    {
        // TODO
    }
}

Providing a Script Editor

This is probably the most tedious part to get working really well. The three most important things to implement here in a commercial application are a good code editor (I suggest using a commercial syntax highlighting control), some form of intellisense or helpers for code creation and background compilation of the script to highlight errors as they are typed, like in Visual Studio. For this article we'll just use a textbox for code editing with no background compilation.

The script editor form needs to be able to accept script source, which will go in to its main editing textbox. It needs to have Ok and Cancel buttons, and a listview to display compile errors should there be any. But most importantly, it needs to be able to compile the script and produce an instance of the class that implements IScript to be handed back to the main form.

You might also like...

Comments

Contribute

Why not write for us? Or you could submit an event or a user group in your area. Alternatively just tell us what you think!

Our tools

We've got automatic conversion tools to convert C# to VB.NET, VB.NET to C#. Also you can compress javascript and compress css and generate sql connection strings.

“If debugging is the process of removing software bugs, then programming must be the process of putting them in.” - Edsger Dijkstra