Skip to content

CLR interop

SetValue projects CLR primitives, delegates, objects, collections, and types into JavaScript.

csharp
var person = new Person { Name = "Ada" };

var engine = new Engine()
    .SetValue("person", person)
    .SetValue("write", new Action<string>(Console.WriteLine));

engine.Execute("write(person.Name)");

Public properties and methods are available through the wrapper. Direct writes to CLR properties, fields, indexers, dictionaries, lists, and live arrays are disabled by default:

csharp
var engine = new Engine(options => options.Interop.AllowWrite = true)
    .SetValue("person", person);

engine.Execute("'use strict'; person.Name = 'Grace'");

AllowWrite does not make objects safe when false. Methods, delegates, and registered extension methods can still mutate host state. Expose only intended capabilities to untrusted scripts.

CLR namespaces and types

Namespace access is disabled by default. Prefer exporting individual values or types. If namespace lookup is required, allow only the needed assemblies:

csharp
var engine = new Engine(options =>
    options.AllowClr(typeof(MyPublicApi).Assembly));

An explicit type can be exported without enabling namespace lookup:

csharp
engine.SetValue(
    "MyPublicApi",
    TypeReference.CreateTypeReference<MyPublicApi>(engine));

An assembly allowlist is not a complete sandbox. An allowed API may load assemblies, access files or networks, start processes, or return more powerful objects. For untrusted code, leave CLR access off or combine a minimal assembly list with a positive TypeResolver.MemberFilter, purpose-built capability objects, and process isolation. Keep AllowGetType and AllowSystemReflection disabled unless they are explicitly required.

Arrays

CLR arrays default to ArrayConversionMode.Copy: scripts receive an independent native JavaScript array. Choose a connected, fixed-size wrapper explicitly:

csharp
var engine = new Engine(options =>
{
    options.Interop.ArrayConversion = ArrayConversionMode.LiveView;
    options.Interop.AllowWrite = true;
});

LiveView makes CLR-side changes visible and, with AllowWrite, lets script change elements. It is not a native JavaScript array and cannot be resized.

See Error handling for exceptions crossing the interop boundary and Performance for repeated projections.