ENTERPRISE

The drive toward DSLs : Running the Scheduling DSL

5/16/2013 7:20:08 PM

We’ve focused on the transformations we’re putting the code through, but we haven’t talked yet about how to compile and execute a DSL. Remember, we aren’t dealing with scripts in the strict sense of the word; we have no interpreter to run. We’re going to compile our DSL to IL, and then execute this IL. The code that it takes to do this isn’t difficult, just annoying to write time after time, so I wrapped it up in a common project called Rhino DSL.

The Rhino DSL project

The Rhino DSL project is a set of components that turned out to be useful across many DSL implementations. It contains classes to aid in building a DSL engine, implicit base classes, multifile DSLs, and so on.


Compilation is expensive, and once we load an assembly in the CLR, we have no way of freeing the occupied memory short of unloading the entire AppDomain. To deal with these two problems, we need to do at least some caching up front. Doing this on a DSL-by-DSL basis is annoying, and it would be nice to get the cost of creating a DSL down as much as possible.

For all of those reasons, Rhino DSL provides the DslFactory class, which takes care of all of that. It works closely with the DslEngine, which is the class we derive from to specify how we want the compilation of the DSL to behave.

Again, none of this is strictly necessary. You can do it yourself easily, if you choose to, but using Rhino DSL makes it easier and allows us to focus on the DSL implementation instead of the compiler mechanics.

We’ve already looked at the BaseScheduler class. Now let’s take a peek at the SchedulingDslEngine class. Listing 1 shows the full source code of the class.

Listing 1. The implementation of SchedulingDslEngine
public class SchedulingDslEngine : DslEngine
{
    protected override void CustomizeCompiler(
        BooCompiler compiler,
        CompilerPipeline pipeline,
        string[] urls)
    {
        pipeline.Insert(1,
            new ImplicitBaseClassCompilerStep(
                typeof (BaseScheduler),
                "Prepare",
                // default namespace imports
                "Rhino.DSL.Tests.SchedulingDSL"));
    }
}

As you can see, it doesn’t do much, but what it does do is interesting. For now, keep in mind that Boo allows you to move code around during compilation, and the ImplicitBaseClassCompilerStep does that.

The ImplicitBaseClassCompilerStep will create an implicit class that will derive from BaseScheduler. All the code in the file will be placed in the Prepare derived method. We can also specify default namespace imports. In listing 1, you can see that we add the Rhino.DSL.Tests.ShedulingDSL namespace. This namespace will be imported to all the DSL scripts, so we don’t have to explicitly import it. VB.NET users are familiar with this feature, using the project imports.

We’re nearly at the point when we can execute our DSL. The one thing that’s still missing is the DslFactory intervention. Listing 2 shows how we can work with that.

Listing 2. Executing a Scheduling DSL script
//initialization
DslFactory factory = new DslFactory();
factory.Register<BaseScheduler>(new SchedulingDslEngine());

//get the DSL instance
BaseScheduler scheduler = factory.Create<BaseScheduler>(
                             @"path/to/ValidateWebSiteUp.boo");

//This is where we run the code from the DSL file
scheduler.Prepare();

//Run the prepared scheduler
scheduler.Run();

First, we initialize the DslFactory, and then create and register a DslEngine for the specific base type we want. Note that you should only do this once, probably during the startup of the application. This usually means in the Main method in console and Windows applications, and in Application_Startup in web applications.

We then get the DSL instance from the factory. We pass both the base type we want (which is associated with the DslEngine that we registered and the return value of this method), and the path to the DSL script. Usually this will be a path in the filesystem, but I have seen embedded resources, URLs, and even source control links used.

Once we have the DSL instance, we can do whatever we want with it. Usually, this depends on the type of DSL it is. When using an imperative DSL, I would tend to call the Run() or Execute() methods. With a declarative DSL, I would usually call a Prepare() or Build() method, which would execute the code that we wrote using the DSL, and then I would call the Run() or Execute() method, which would take the result of the previous method call and act upon it. In more complex scenarios, you might ask a separate class to process the results, instead of having the base class share both responsibilities.

In the case of the Scheduling DSL, we use a declarative approach, so we call the Prepare() method to get whatever declarations were made in the DSL, and then we run the code. The Run() method in such a DSL will usually perform some sort of registration into a scheduling engine.

And that’s it—all the building blocks that you need to write a good DSL. We’re going to spend a lot more time discussing all the things we can do with DSLs, how we can integrate them into real applications, and version, test, and deploy them, but you should now have an overall understanding of what’s involved.

Other  
  •  Visual Studio Team System 2008 : Deploying and Running Tests (part 2)
  •  Visual Studio Team System 2008 : Deploying and Running Tests (part 1) - Remote deployment, Deploy additional files
  •  Programming Excel with VBA and .NET : Expressions, Exceptions
  •  Programming Excel with VBA and .NET : Loops
  •  Programming Excel with VBA and .NET : Conditional Statements
  •  Microsoft Content Management Server Development : Building SharePoint Web Parts - Adding Our Web Part to a Page
  •  Microsoft Content Management Server Development : Building SharePoint Web Parts - Web Part Deployment
  •  Windows Presentation Foundation in .NET 4 : Dependency Properties - Property Validation
  •  Windows Presentation Foundation in .NET 4 : Understanding Dependency Properties
  •  Combat Virtual Threats With IPCop Firewall (Part 2)
  •  
    Video
    Video tutorials
    - How To Install Windows 8

    - How To Install Windows Server 2012

    - How To Install Windows Server 2012 On VirtualBox

    - How To Disable Windows 8 Metro UI

    - How To Install Windows Store Apps From Windows 8 Classic Desktop

    - How To Disable Windows Update in Windows 8

    - How To Disable Windows 8 Metro UI

    - How To Add Widgets To Windows 8 Lock Screen

    - How to create your first Swimlane Diagram or Cross-Functional Flowchart Diagram by using Microsoft Visio 2010
    programming4us programming4us
    Top 10
    Free Mobile And Desktop Apps For Accessing Restricted Websites
    MASERATI QUATTROPORTE; DIESEL : Lure of Italian limos
    TOYOTA CAMRY 2; 2.5 : Camry now more comely
    KIA SORENTO 2.2CRDi : Fuel-sipping slugger
    How To Setup, Password Protect & Encrypt Wireless Internet Connection
    Emulate And Run iPad Apps On Windows, Mac OS X & Linux With iPadian
    Backup & Restore Game Progress From Any Game With SaveGameProgress
    Generate A Facebook Timeline Cover Using A Free App
    New App for Women ‘Remix’ Offers Fashion Advice & Style Tips
    SG50 Ferrari F12berlinetta : Prancing Horse for Lion City's 50th
    Popular Tags
    Video Tutorail Microsoft Access Microsoft Excel Microsoft OneNote Microsoft PowerPoint Microsoft Project Microsoft Visio Microsoft Word Active Directory Exchange Server Sharepoint Sql Server Windows Server 2008 Windows Server 2012 Windows 7 Windows 8 Adobe Flash Professional Dreamweaver Adobe Illustrator Adobe Photoshop CorelDRAW X5 CorelDraw 10 windows Phone 7 windows Phone 8 Iphone