I'm looking at converting our application from using JavaScript.NET (Noesis) to use ClearScript.
Our app contains a large number of user-created Javascript algorithms/expressions for financial calculations - I'd rather avoid having to change those if possible.
Currently with JavaScript.NET many of the user-defined algorithms follow a pattern of creating a JavaScript array containing host types and passing that as a parameter to a function on another host type. With JavaScript.NET that conversion "just works". See code below for what I'm trying to do:
using System;
using Microsoft.ClearScript;
using Microsoft.ClearScript.V8;
namespace ClearscriptPlayground
{
class Program
{
static void Main(string[] args)
{
using (var engine = new V8ScriptEngine())
{
var myClass = new MyClass();;
engine.AddHostObject("instance", myClass);
engine.AddHostType("MyType", HostItemFlags.DirectAccess, typeof(MyType));
engine.Execute(
@"var params = [new MyType('bye', 10),
new MyType('hello', 10)];
instance.SomethingElse(params)");
Console.ReadLine();
}
}
}
public class MyClass
{
// public void SomethingElse(ITypedArray<MyType> foo)
// {
// // Doesn't work.
// }
// public void SomethingElse(MyType[] foo)
// {
// // Doesn't work.
// }
// public void SomethingElse(dynamic foo)
// {
// var mapped = foo as ITypedArray<MyType>; // Doesn't work
// var mapped = foo as MyType[]; // Doesn't work either
// }
public void SomethingElse(ScriptObject foo)
{
// Works, but how best to convert to MyType[] or similar?
}
}
public struct MyType
{
public string Foo;
public int Bar;
public MyType(string foo, int bar)
{
Foo = foo;
Bar = bar;
}
}
}
NB: I know that I can create a host array using params = host.newArr(MyType, 2);
and that will work - but that would mean modifying all the user-maintained JavaScript which I'd really rather avoid.
You can use the JavaScript array directly via dynamic
:
public void SomethingElse(dynamic foo)
{
var length = foo.length;
for (var i = 0; i < length; ++i)
{
var my = (MyType)foo[i];
Console.WriteLine("{0} {1}", my.Foo, my.Bar);
}
}