Well, DLR hosting API has been all over the place and some of the obvious convenient methods in IronPython 1.1 such as CreateMethod disappears. The latest DLR hosting spec was released on Jan 3, 2008 and it was out of sync from the latest IronPython 2 Beta 1.

 

I spent a couple of hours yesterday to investigate the new DLR hosting implementation in IronPython 2 Beta 1 and have successfully figured out the "new ways" of DLR hosting API.

 

Copy these codes and run it in your environment. Replace the "X2" or "2" suffix in some of the namespace. I had to do this because I am working on a CMS that works on ASP.Net Futures 2007 release with IronPython 2 Alpha 1 as the implemenation for the asp.net support  and I have a code execution engine that I want to upgrade from IronPython 1.1 to the latest beta. Naturally those two IronPython runtime clashed and I have to recompile the IronPython Beta 2 with new namespace and assembly name.

 

The following codes demonstrate of the capabilities for the "hosting scenario level 2" (per DLR hosting spec). Enjoy.

 

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.Scripting2.Hosting;
using IronPythonX2.Hosting;
using IronPythonX2.Modules;
using IronPythonX2.Runtime;
using IronPythonX2.Runtime.Exceptions;
using MbUnit.Framework;
using Microsoft.Scripting2;
using Microsoft.Scripting2.Runtime;

namespace HostingRunner
{

    public class Simple
    {

        ScriptEngine _engine;
        ScriptScope _scope;
        public Simple()
        {
            _engine = ScriptRuntime.Create().GetEngine("py");

            var sy = new SymbolDictionary()
            {
                { SymbolTable.StringToId("n"), 10}
            };
            _scope = _engine.CreateScope(sy);
        }

        public string ExecuteBLOCKED EXPRESSION
        {
            _scope.SetVariable("n", 10);

            var code = @"
x = 1 + 1
";
            var compiledCode = _engine.CreateScriptSourceFromString(code, Microsoft.Scripting2.SourceCodeKind.Statements);

            try
            {
                compiledCode.Execute(_scope);
                return _scope.GetVariable<int>("x").ToString();
            }
            catch (Microsoft.Scripting2.SyntaxErrorException e)
            {
                return e.Line + " : " + e.Column + " : " + e.Message;
            }
            catch (Exception e)
            {
                return e.Message;
            }
        }

        public string CreateMethod()
        {
            var code = @"
def function():
    return 1 + 1 + 200

";
            var sourceCode = _engine.CreateScriptSourceFromString(code, Microsoft.Scripting2.SourceCodeKind.Statements);

            sourceCode.Execute(_scope);

            return _engine.GetVariable<Func<int>>(_scope, "function")().ToString();

        }

        public string CallOneCodeMultipleScope()
        {
            _scope.SetVariable("n", 16);

            var code = @"
def function():
    return 1 + n

";
            var compiledCode = _engine.CreateScriptSourceFromString(code, Microsoft.Scripting2.SourceCodeKind.Statements).Compile();
            compiledCode.Execute(_scope);

            var firstResult = _engine.GetVariable<Func<int>>(_scope, "function")();

            var secondScope = _engine.CreateScope();
            secondScope.SetVariable("n", 10);

            var secondResult = _engine.GetVariable<Func<int>>(_scope, "function")();

            return (firstResult + secondResult).ToString();
        }

        public string CallMultipleExecutionOverASingleScope()
        {
            var code = @"
def function():
    return 1 + 1";

            _engine.CreateScriptSourceFromString(code, Microsoft.Scripting2.SourceCodeKind.Statements).Execute(_scope);

            var code2 = @"
def function2():
    return 10 + function()
";
            var compiledCode = _engine.CreateScriptSourceFromString(code2, SourceCodeKind.Statements).Compile();

            compiledCode.Execute(_scope);

            return _engine.GetVariable<Func<int>>(_scope, "function2")().ToString();
        }

        public string CallLoadExternalAssembly()
        {
            _engine.Runtime.LoadAssembly(System.Reflection.Assembly.LoadWithPartialName("SK.Framework"));

            var code = @"
import clr
clr.AddReference(""SK.Framework"")
from SK.Framework import Unique
";

            _engine.CreateScriptSourceFromString(code, Microsoft.Scripting2.SourceCodeKind.Statements).Execute(_scope);

            var code2 = @"
def function2():
    return Unique.Empty.Value
";
            var compiledCode = _engine.CreateScriptSourceFromString(code2, SourceCodeKind.Statements).Compile();

            compiledCode.Execute(_scope);

            return _engine.GetVariable<Func<int>>(_scope, "function2")().ToString();
        }
    }
}

namespace HostingRunner
{
    [TestFixture]
    public class SimpleTest
    {
        Simple _simple;
        [SetUp]
        public void Setup()
        {
            _simple = new Simple();
        }

        [Test]
        public void TestScope()
        {
            var value = _simple.ExecuteBLOCKED EXPRESSION;

            Assert.IsTrue(value == "2", "value must be equal 1 + 1 instead of " + value);
        }

        [Test]
        public void TestDelegate()
        {
            var value = _simple.CreateMethod();

            Assert.IsTrue(value == "2", "value must be equal 1 + 1 instead of " + value);
        }

        [Test]
        public void TestCompiledCode()
        {
            var value = _simple.CallOneCodeMultipleScope();

            Assert.IsTrue(value == "34", "value must be equal 1 + 1 instead of " + value);
        }

        [Test]
        public void TestMultipleExecution()
        {
            var value = _simple.CallMultipleExecutionOverASingleScope();

            Assert.IsTrue(value == "12", "value must be equal 55 instead of " + value);
        }

        [Test]
        public void TestReference()
        {
            var value = _simple.CallLoadExternalAssembly();

            Assert.IsTrue(value == "-12", "value must be equal 12 instead of " + value);
        }
    }

}