I need to add lightweight scripting capability to my application.
Creating assemblies requires to design interfaces passed to scripts.
Assemblies cannot be unloaded in same appdomain, parameters cannot easily
passed
to other appdomain.
So I want to create scripts as current assembly methods.
How about using JScript.NET and its eval() function? Admittingly, I do
not know how exactly it is implemented, but given its nature and
frequent use in JavaScript it can hardly be done by generating a new
assembly every time. Now, eval() is a built-in function, and you
cannot call it from C# directly, but you can write an assembly in
JScript that wraps a call to eval() into a plain .NET class. Something
like this:
// Evaluator.js
import System;
public class Evaluator
{
function Eval(script : String) : Object
{
return eval(script);
}
}
Compile it with "jsc /t:library", and then add a reference to the
resulting assembly to your application. The only caveat is that you'll
also need to reference Microsoft.JScript assembly. After that, the
usage is straightforward. Here's a simple JScript REPL in C#:
// Program.cs
using System;
using Microsoft.JScript;
class Program
{
static void Main()
{
var evaluator = new Evaluator();
while (true)
{
Console.Write("> ");
var script = Console.ReadLine();
if (script == string.Empty)
{
break;
}
try
{
var result = evaluator.Eval(script);
Console.WriteLine(result);
}
catch (JScriptException ex)
{
Console.WriteLine("Error: " + ex.Message);
}
}
}
}
Try entering this at the prompt to test it:
for (var i = 0; i < 10; ++i) System.Console.WriteLine(i)
Another problem with that approach is that in JScript, you need to
import a namespace (using "import" statement) before you can use any
types from it. Worse, code inside eval() cannot import anything - it
can only use namespaces that were imported at the point where eval()
itself was called - in this case, in Evaluator.js. So, you'll need to
import all namespaces you want to access in your script from there.