Evaluate the script that defines the function, read the function from the global object with GetProperty, and call it with engine.Call. The program below calls a pricing function from a script with C# arguments.
dotnet new console -o CallJs && cd CallJs dotnet add package RecursiveAI.OneEcma --version 1.0.0
Put this in Program.cs and run dotnet run:
using RecursiveAI.OneEcma; var engine = new ScriptEngine(); engine.Evaluate(""" function price(qty, unit, code) { if (qty <= 0) throw new RangeError(`qty must be positive, got ${qty}`); const discount = code === "SPRING" ? 0.1 : 0; return Math.round(qty * unit * (1 - discount) * 100) / 100; } """, "pricing.js"); JsValue price = engine.GetProperty(engine.Global, "price"); JsValue a = engine.Call(price, default, [JsValue.FromNumber(12), JsValue.FromNumber(2.5), JsValue.FromString("SPRING")]); JsValue b = engine.Call(price, default, [JsValue.FromNumber(3), JsValue.FromNumber(9.99), JsValue.FromString("")]); Console.WriteLine($"{a.AsNumber} and {b.AsNumber}"); try { engine.Call(price, default, [JsValue.FromNumber(0), JsValue.FromNumber(1), JsValue.FromString("")]); } catch (JsException e) // what the script threw, as a .NET exception { Console.WriteLine(e.Message); }
27 and 29.97 RangeError: qty must be positive, got 0
default is the this value, here undefined. Arguments are JsValues: FromNumber, FromString, FromBoolean and FromObject make them. An exception thrown in the script comes back as a JsException with the script’s message, and e.Report holds a full report with the line that threw.
Calling it many times
Evaluate the script once and keep the engine and the function: each Call runs only the function. Pass a CancellationToken as the last argument of Call to stop a call that takes too long, or set limits on the engine.
Limits
- One engine per thread. Calls into the same engine must come from one thread at a time.
- Async functions return a promise. Call
engine.RunJobs()to run pending jobs, then read the promise withengine.MainRealm.AsPromise(value). - Modules: a function exported from an ES module isn’t on the global object. Load modules with
EvaluateModuleand a host that resolves them (Runtime and the host).
To run a script and read its result without a function, see Run JavaScript in C#. To go the other way, see Call C# from JavaScript.