<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>The Grubbsian &#187; IronPython</title>
	<atom:link href="http://www.thegrubbsian.com/category/ironpython/feed/" rel="self" type="application/rss+xml" />
	<link>http://www.thegrubbsian.com</link>
	<description>Writings on .NET, Ruby, JavaScript, HTML/CSS, Design, and all things Web.</description>
	<lastBuildDate>Sun, 01 Aug 2010 20:57:19 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.0.1</generator>
		<item>
		<title>Scriptability via the DLR and PostSharp</title>
		<link>http://www.thegrubbsian.com/2009/12/15/scriptability-via-the-dlr-and-postsharp/</link>
		<comments>http://www.thegrubbsian.com/2009/12/15/scriptability-via-the-dlr-and-postsharp/#comments</comments>
		<pubDate>Tue, 15 Dec 2009 21:28:13 +0000</pubDate>
		<dc:creator>JC Grubbs</dc:creator>
				<category><![CDATA[.NET]]></category>
		<category><![CDATA[IronPython]]></category>
		<category><![CDATA[DLR]]></category>

		<guid isPermaLink="false">http://www.thegrubbsian.com/?p=265</guid>
		<description><![CDATA[Making an application scriptable (particularly in a static language) has historically been difficult. With the advent of the DLR (Dynamic Language Runtime) on the .NET platform it becomes almost trivial to add scripting support to any application. For a recent project I needed the ability to add scripting hooks throughout the application and coupling the [...]]]></description>
			<content:encoded><![CDATA[<p>Making an application scriptable (particularly in a static language) has historically been difficult.  With the advent of the DLR (Dynamic Language Runtime) on the .NET platform it becomes almost trivial to add scripting support to any application.  For a recent project I needed the ability to add scripting hooks throughout the application and coupling the DLR with PostSharp AOP attributes made this effort pretty straightforward.  Here&#8217;s how it was done:</p>
<p><strong>Bring in the DLR</strong><br />
The DLR is implemented as a set of plain old DLL&#8217;s on top of the .NET Framework version 3.5&#8230;contrary to popular belief, you do not have to be running VS2010 or .NET 4 to use it.  Simply go to the CodePlex page for the DLR (<a href="http://dlr.codeplex.com">http://dlr.codeplex.com</a>), grab the source, and compile it.  There are solution files for VS2008 and VS2010.</p>
<p>For my purposes I used IronPython as the scripting language but IronRuby is available in the download as well.  To use the DLR your project will need to reference the following assemblies:</p>
<ul>
<li>Microsoft.Dynamic.dll</li>
<li>Microsoft.Scripting.Core.dll</li>
<li>Microsoft.Scripting.dll</li>
</ul>
<p>In order to use IronPython, you will also need to reference these:</p>
<ul>
<li>IronPython.dll</li>
<li>IronPython.Modules.dll</li>
<li>Microsoft.Scripting.ExtensionAttribute.dll</li>
</ul>
<p><strong>Register the Languages</strong><br />
Now that your project contains all the references it needs it&#8217;s time to set up the little bit of code needed to host the DLR.  First you&#8217;ll need to add a few things to your configuration file (App.config or Web.config depending on your project type&#8230;this works equally well with either).  Just add the following to the <configSections> node of your config file:</p>

<div class="wp_syntax"><div class="code"><pre class="xml" style="font-family:monospace;"><span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;section</span> <span style="color: #000066;">name</span>=<span style="color: #ff0000;">&quot;microsoft.scripting&quot;</span> </span>
<span style="color: #009900;">	<span style="color: #000066;">type</span>=<span style="color: #ff0000;">&quot;Microsoft.Scripting.Hosting.Configuration.Section, Microsoft.Scripting, </span>
<span style="color: #009900;">		Version=0.9.6.20, Culture=neutral, PublicKeyToken=null&quot;</span> </span>
<span style="color: #009900;">	<span style="color: #000066;">requirePermission</span>=<span style="color: #ff0000;">&quot;false&quot;</span> <span style="color: #000000; font-weight: bold;">/&gt;</span></span></pre></div></div>

<p>And add the following somewhere in the root <configuration> node:</p>

<div class="wp_syntax"><div class="code"><pre class="xml" style="font-family:monospace;"><span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;microsoft.scripting<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
    <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;languages<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
        <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;language</span> <span style="color: #000066;">names</span>=<span style="color: #ff0000;">&quot;IronPython;Python;py&quot;</span> </span>
<span style="color: #009900;">			<span style="color: #000066;">extensions</span>=<span style="color: #ff0000;">&quot;.py&quot;</span> <span style="color: #000066;">displayName</span>=<span style="color: #ff0000;">&quot;IronPython 2.6&quot;</span> </span>
<span style="color: #009900;">			<span style="color: #000066;">type</span>=<span style="color: #ff0000;">&quot;IronPython.Runtime.PythonContext, IronPython, </span>
<span style="color: #009900;">				Version=2.6.10920.0, Culture=neutral, PublicKeyToken=null&quot;</span> <span style="color: #000000; font-weight: bold;">/&gt;</span></span>
    <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/languages<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/microsoft.scripting<span style="color: #000000; font-weight: bold;">&gt;</span></span></span></pre></div></div>

<p>This basically just tells the runtime what languages to register, what versions of those languages, and some info about file extensions, etc.</p>
<p><strong>Bring in PostSharp</strong><br />
Now I&#8217;m going to skip over to PostSharp for a minute.  If you&#8217;re not familiar with PostSharp you should run over to the website (<a href="http://www.postsharp.org">http://www.postsharp.org</a>) and check it out before continuing.  In short, it&#8217;s an AOP (Aspect Oriented Programming) library for .NET that allows easy injection of cross-cutting concerns through an application primarily via attributes.  The 10sec. version of how it works is this&#8230;it injects code in a post-compilation step.  This sounds scary, but it&#8217;s not.  In fact, this allows it to be extremely fast at runtime even if a small penalty is paid at compile-time.</p>
<p>In order to get PostSharp setup, it&#8217;s a simple download and install.  If you don&#8217;t want to install it on your machine, you can simply bin deploy it but it does require a tweak to your .proj file to get the post-compilation to work.  If you want to go that route, you can <a href="http://doc.postsharp.org/1.5/##PostSharp.HxS/UserGuide/Platform/EnablingPostSharp.html">find instructions here</a>.  At this point you will either follow those instructions or if you&#8217;ve installed directly, just include the following assemblies in your project:</p>
<ul>
<li>PostSharp.Laos.dll</li>
<li>PostSharp.Public.dll</li>
</ul>
<p><strong>The ScriptHook Attribute</strong><br />
PostSharp&#8217;s primary way of injecting an aspect is through attributes.  In our case we&#8217;re going to inherit from the OnMethodBoundaryAspect attribute in the PostSharp.Laos namespace.  This attribute exposes four virtual methods that allow injection of code at different points in the execution of a method:</p>
<ul>
<li>OnEntry</li>
<li>OnExit</li>
<li>OnException</li>
<li>OnSuccess</li>
</ul>
<p>Each of these methods accept a MethodExecutionEventArgs as an argument that provides access (including arguments) to the method on which the attribute is applied.  Here&#8217;s the ScriptHook attribute:</p>

<div class="wp_syntax"><div class="code"><pre class="csharp" style="font-family:monospace;"><span style="color: #000000;">&#91;</span>Serializable<span style="color: #000000;">&#93;</span>
<span style="color: #0600FF;">public</span> <span style="color: #FF0000;">class</span> ScriptHookAttribute <span style="color: #008000;">:</span> OnMethodBoundaryAspect <span style="color: #000000;">&#123;</span>
&nbsp;
    <span style="color: #0600FF;">private</span> <span style="color: #0600FF;">readonly</span> ScriptEventTypes _scriptEventType<span style="color: #008000;">;</span>
&nbsp;
    <span style="color: #0600FF;">public</span> ScriptEventAttribute<span style="color: #000000;">&#40;</span>ScriptEventTypes scriptEventType<span style="color: #000000;">&#41;</span> <span style="color: #000000;">&#123;</span>
        _scriptEventType <span style="color: #008000;">=</span> scriptEventType<span style="color: #008000;">;</span>
    <span style="color: #000000;">&#125;</span>
&nbsp;
    <span style="color: #0600FF;">public</span> <span style="color: #0600FF;">override</span> <span style="color: #0600FF;">void</span> OnSuccess<span style="color: #000000;">&#40;</span>MethodExecutionEventArgs eventArgs<span style="color: #000000;">&#41;</span> <span style="color: #000000;">&#123;</span>
        var args <span style="color: #008000;">=</span> eventArgs.<span style="color: #0000FF;">GetReadOnlyArgumentArray</span><span style="color: #000000;">&#40;</span><span style="color: #000000;">&#41;</span><span style="color: #008000;">;</span>
        ScriptRunner.<span style="color: #0000FF;">ExecuteEvent</span><span style="color: #000000;">&#40;</span>_scriptEventType, args<span style="color: #000000;">&#41;</span><span style="color: #008000;">;</span>
    <span style="color: #000000;">&#125;</span>
<span style="color: #000000;">&#125;</span></pre></div></div>

<p>For now, ignore the ScriptRunner reference, but notice that I&#8217;ve created an enum (ScriptEventTypes) that distinguishes different &#8220;types&#8221; of scripts to be run, by types, I mean different usages.  At some point you can switch on the type of event that&#8217;s occurring and change which scripts are loaded or how they are handled, etc.  You would use the attribute like this:</p>

<div class="wp_syntax"><div class="code"><pre class="csharp" style="font-family:monospace;"><span style="color: #000000;">&#91;</span>ScriptHook<span style="color: #000000;">&#40;</span>ScriptEventTypes.<span style="color: #0000FF;">ThingSaved</span><span style="color: #000000;">&#41;</span><span style="color: #000000;">&#93;</span>
<span style="color: #0600FF;">public</span> <span style="color: #0600FF;">void</span> SaveThing<span style="color: #000000;">&#40;</span>Thing t<span style="color: #000000;">&#41;</span> <span style="color: #000000;">&#123;</span> <span style="color: #000000;">&#125;</span>
&nbsp;
<span style="color: #000000;">&#91;</span>ScriptHook<span style="color: #000000;">&#40;</span>ScriptEventTypes.<span style="color: #0000FF;">ThingDeleted</span><span style="color: #000000;">&#41;</span><span style="color: #000000;">&#93;</span>
<span style="color: #0600FF;">public</span> <span style="color: #0600FF;">void</span> DeleteThing<span style="color: #000000;">&#40;</span>Thing t<span style="color: #000000;">&#41;</span> <span style="color: #000000;">&#123;</span> <span style="color: #000000;">&#125;</span></pre></div></div>

<p><strong>The ScriptRunner</strong><br />
At this point we&#8217;ve got the DLR available and we have the PostSharp attribute that&#8217;s injecting our hooks.  Now we need something to execute our scripts.  Enter the ScriptRunner:</p>

<div class="wp_syntax"><div class="code"><pre class="csharp" style="font-family:monospace;"><span style="color: #0600FF;">public</span> <span style="color: #0600FF;">static</span> <span style="color: #FF0000;">class</span> ScriptRunner <span style="color: #000000;">&#123;</span>
&nbsp;
    <span style="color: #0600FF;">public</span> <span style="color: #0600FF;">static</span> <span style="color: #0600FF;">void</span> ExecuteEvent<span style="color: #000000;">&#40;</span>ScriptEventTypes scriptEventType, <span style="color: #FF0000;">object</span><span style="color: #000000;">&#91;</span><span style="color: #000000;">&#93;</span> eventContext<span style="color: #000000;">&#41;</span> <span style="color: #000000;">&#123;</span>
&nbsp;
    IScriptEvent scriptEvent <span style="color: #008000;">=</span> null<span style="color: #008000;">;</span>
&nbsp;
    <span style="color: #0600FF;">switch</span> <span style="color: #000000;">&#40;</span>scriptEventType<span style="color: #000000;">&#41;</span> <span style="color: #000000;">&#123;</span>
        <span style="color: #0600FF;">case</span> ScriptEventTypes.<span style="color: #0000FF;">ThingSaved</span><span style="color: #008000;">:</span>
	    scriptEvent <span style="color: #008000;">=</span> <span style="color: #008000;">new</span> ThingSavedScriptEvent<span style="color: #000000;">&#40;</span><span style="color: #000000;">&#41;</span><span style="color: #008000;">;</span>
	    break<span style="color: #008000;">;</span>
	<span style="color: #0600FF;">case</span> ScriptEventTypes.<span style="color: #0000FF;">ThingDeleted</span><span style="color: #008000;">:</span>
	    scriptEvent <span style="color: #008000;">=</span> <span style="color: #008000;">new</span> ThingDeletedScriptEvent<span style="color: #008000;">;</span>
	    break<span style="color: #008000;">;</span>
	<span style="color: #000000;">&#125;</span>
&nbsp;
	<span style="color: #0600FF;">if</span> <span style="color: #000000;">&#40;</span>scriptEvent <span style="color: #008000;">!=</span> <span style="color: #0600FF;">null</span><span style="color: #000000;">&#41;</span> <span style="color: #000000;">&#123;</span>
            <span style="color: #0600FF;">try</span> <span style="color: #000000;">&#123;</span>
                scriptEvent.<span style="color: #0000FF;">ExecuteScripts</span><span style="color: #000000;">&#40;</span>eventContext<span style="color: #000000;">&#41;</span><span style="color: #008000;">;</span>
            <span style="color: #000000;">&#125;</span> <span style="color: #0600FF;">catch</span> <span style="color: #000000;">&#123;</span>
                <span style="color: #0600FF;">throw</span> <span style="color: #008000;">new</span> ScriptExecutionExecption<span style="color: #000000;">&#40;</span><span style="color: #000000;">&#41;</span><span style="color: #008000;">;</span>
            <span style="color: #000000;">&#125;</span>
        <span style="color: #000000;">&#125;</span>
    <span style="color: #000000;">&#125;</span>
<span style="color: #000000;">&#125;</span></pre></div></div>

<p>The runner is just a simple static class with a single ExecuteEvent method&#8230;it&#8217;s so simple in fact that it speaks for itself.  The one thing to note is the eventContext argument to the ExecuteEvent method.  If you look back at the ScriptHook attribute you can see that is&#8217; passing an object array from the MethodExecutionEventArgs instance.  This object array contains all the arguments to the executing method.  So for SaveThing() or DeleteThing() for example the eventContext array contains the instance of Thing that was passed.</p>
<p><strong>The IScriptEvent Classes</strong><br />
Lastly, we need something to actually grab the scripts and execute them in something like the context of the executing method.  So that&#8217;s where our example ThingSavedScriptEvent and ThingDeletedScriptEvent come in to play.  Here&#8217;s an example:</p>

<div class="wp_syntax"><div class="code"><pre class="csharp" style="font-family:monospace;"><span style="color: #0600FF;">public</span> <span style="color: #FF0000;">class</span> ThingSavedScriptEvent <span style="color: #008000;">:</span> IScriptEvent <span style="color: #000000;">&#123;</span>
&nbsp;
    <span style="color: #0600FF;">private</span> <span style="color: #0600FF;">readonly</span> ScriptRuntime _scriptRuntime<span style="color: #008000;">;</span>
    <span style="color: #0600FF;">private</span> <span style="color: #0600FF;">readonly</span> IThingRepository _thingRepo<span style="color: #008000;">;</span>
&nbsp;
    <span style="color: #0600FF;">public</span> ProjectCreatedScriptEvent<span style="color: #000000;">&#40;</span><span style="color: #000000;">&#41;</span> <span style="color: #000000;">&#123;</span>
        _thingRepo <span style="color: #008000;">=</span> <span style="color: #008000;">new</span> ThingRepository<span style="color: #000000;">&#40;</span><span style="color: #000000;">&#41;</span><span style="color: #008000;">;</span>
        _scriptRuntime <span style="color: #008000;">=</span> ScriptRuntime.<span style="color: #0000FF;">CreateFromConfiguration</span><span style="color: #000000;">&#40;</span><span style="color: #000000;">&#41;</span><span style="color: #008000;">;</span>
    <span style="color: #000000;">&#125;</span>
&nbsp;
    <span style="color: #0600FF;">public</span> <span style="color: #0600FF;">void</span> ExecuteScripts<span style="color: #000000;">&#40;</span><span style="color: #FF0000;">object</span><span style="color: #000000;">&#91;</span><span style="color: #000000;">&#93;</span> contextValues<span style="color: #000000;">&#41;</span> <span style="color: #000000;">&#123;</span>
&nbsp;
        var thing <span style="color: #008000;">=</span> <span style="color: #000000;">&#40;</span>Thing<span style="color: #000000;">&#41;</span>contextValues.<span style="color: #0000FF;">SingleOrDefault</span><span style="color: #000000;">&#40;</span>x <span style="color: #008000;">=&gt;</span> x <span style="color: #008000;">is</span> Thing<span style="color: #000000;">&#41;</span><span style="color: #008000;">;</span>
&nbsp;
		var scriptScope <span style="color: #008000;">=</span> _scriptRuntime.<span style="color: #0000FF;">CreateScope</span><span style="color: #000000;">&#40;</span><span style="color: #000000;">&#41;</span><span style="color: #008000;">;</span>
        scriptScope.<span style="color: #0000FF;">SetVariable</span><span style="color: #000000;">&#40;</span><span style="color: #666666;">&quot;thingRepo&quot;</span>, _thingRepo<span style="color: #000000;">&#41;</span><span style="color: #008000;">;</span>
        scriptScope.<span style="color: #0000FF;">SetVariable</span><span style="color: #000000;">&#40;</span><span style="color: #666666;">&quot;thing&quot;</span>, thing<span style="color: #000000;">&#41;</span><span style="color: #008000;">;</span>
&nbsp;
        var script <span style="color: #008000;">=</span> GetScript<span style="color: #000000;">&#40;</span><span style="color: #000000;">&#41;</span><span style="color: #008000;">;</span>
&nbsp;
        var scriptEngine <span style="color: #008000;">=</span> _scriptRuntime.<span style="color: #0000FF;">GetEngine</span><span style="color: #000000;">&#40;</span><span style="color: #666666;">&quot;IronPython&quot;</span><span style="color: #000000;">&#41;</span><span style="color: #008000;">;</span>
        scriptEngine.<span style="color: #0000FF;">Execute</span><span style="color: #000000;">&#40;</span>script, scriptScope<span style="color: #000000;">&#41;</span><span style="color: #008000;">;</span>
    <span style="color: #000000;">&#125;</span>
&nbsp;
    <span style="color: #0600FF;">private</span> <span style="color: #0600FF;">static</span> <span style="color: #FF0000;">string</span> GetScript<span style="color: #000000;">&#40;</span><span style="color: #000000;">&#41;</span> <span style="color: #000000;">&#123;</span>
&nbsp;
        var script <span style="color: #008000;">=</span> <span style="color: #FF0000;">string</span>.<span style="color: #0000FF;">Empty</span><span style="color: #008000;">;</span>
        <span style="color: #0600FF;">try</span> <span style="color: #000000;">&#123;</span>
            code <span style="color: #008000;">=</span> File.<span style="color: #0000FF;">ReadAllText</span><span style="color: #000000;">&#40;</span>HttpContext.<span style="color: #0000FF;">Current</span>.<span style="color: #0000FF;">Server</span>.<span style="color: #0000FF;">MapPath</span><span style="color: #000000;">&#40;</span>
                ConfigSettings.<span style="color: #0000FF;">ProjectTemplateStorePath</span> <span style="color: #008000;">+</span> <span style="color: #666666;">&quot;ThingSaved.py&quot;</span><span style="color: #000000;">&#41;</span><span style="color: #000000;">&#41;</span><span style="color: #008000;">;</span>
        <span style="color: #000000;">&#125;</span> <span style="color: #0600FF;">catch</span> <span style="color: #000000;">&#40;</span>FileNotFoundException<span style="color: #000000;">&#41;</span> <span style="color: #000000;">&#123;</span> <span style="color: #000000;">&#125;</span>
        <span style="color: #0600FF;">return</span> script<span style="color: #008000;">;</span>
    <span style="color: #000000;">&#125;</span>
<span style="color: #000000;">&#125;</span></pre></div></div>

<p>The ScriptRuntime class is where the DLR magic happens.  We create an instance of it and then ask it for an engine that can execute IronPython scripts.  ScriptScope is a class used for constructing the scope that the script will have available to it.  Here for example we&#8217;re &#8220;passing&#8221; the &#8216;thingRepo&#8217; and &#8216;thing&#8217; variables into the script via the ScriptScope.  Lastly, we get the engine from the ScriptRuntime, pass it both the ScriptScope and the literal text of the script.  And that&#8217;s that&#8230;pretty easy eh?</p>
]]></content:encoded>
			<wfw:commentRss>http://www.thegrubbsian.com/2009/12/15/scriptability-via-the-dlr-and-postsharp/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
	</channel>
</rss>
