Jint. How to set property of class, or invoke method, of class?

882 Views Asked by At

With Jint how can I set a property (or invoke a method) of an instance of a javascript class?

e.g. if I do:

var o = new Jint.Engine().Evaluate(@"
class MyClass {
  constructor() {
     this.myProperty = null;
  }
}

const o = new MyClass;
return o;
");

how do I then set the myProperty value of the returned o object?

This is using Jint v3.

1

There are 1 best solutions below

2
BenderBoy On

To access stuff you got back from Jint, you turn it into an object by calling ToObject() on it and declare it as dynamic so you can use arbitrary properties:

dynamic o = new Jint.Engine().Evaluate(
@"
class MyClass {
  constructor() {
     this.myProperty = null;
  }
}

const o = new MyClass;
return o;
").ToObject();

Console.WriteLine(o?.GetType() ?? "<null>"); //System.Dynamic.ExpandoObject

Console.WriteLine(o?.myProperty ?? "<null>"); //<null>

o.myProperty = "why not this string";
Console.WriteLine(o?.myProperty ?? "<null>"); //why not this string
Console.WriteLine(o?.myProperty?.GetType() ?? "<null>"); //System.String

o.myProperty = 99;
Console.WriteLine(o?.myProperty ?? "<null>"); //99
Console.WriteLine(o?.myProperty?.GetType() ?? "<null>"); //System.Int32

Now AFAIK there is no built-in way to change a property and continue working with it in the Javascript. Two options I can think of:

  1. Declare the class in C# and pass an instance to Jint via SetValue(). Changes to the object instance will be available in Jint.

  2. Hack up something like this to change arbitrary stuff from within Jint:

public static void SetProperty(this Jint.Engine engine, string propertyPath, object value)
{
    string tempname = "super_unique_name_that_will_never_collide_with_anything";
    engine.SetValue(tempname, value);
    engine.Evaluate($@"{propertyPath} = {tempname}; delete globalThis.{tempname};");
}