ClearScript icon indicating copy to clipboard operation
ClearScript copied to clipboard

is any way to support string extension method?

Open coader opened this issue 3 years ago • 2 comments

because can't use addhostobject to add string variable so can't use any string's extension methods even already add thus code: _engine.AddHostType(typeof(StringExtensions));

coader avatar Aug 10 '22 16:08 coader

Hi @coader,

First, we should mention that, if your extensions can be implemented entirely in script code, you can simply add them to the String prototype. That's an efficient approach, as it avoids expensive script-to-host calls.

If you must use managed extensions, you can still use a similar approach. The following method adds managed extensions to any JavaScript prototype:

private static void AddPrototypeExtensions(ScriptEngine engine, string ctorName, Type type) {
    dynamic setupFunc = engine.Evaluate(@"(function (ctor, ext, names) {
        for (const name of names)
            ctor.prototype[name] = function () { return ext[name](this.valueOf(), ...arguments); };
    })");
    var names = from method in type.GetMethods(BindingFlags.Public | BindingFlags.Static)
        where Attribute.IsDefined(method, typeof(ExtensionAttribute))
        select method.Name;
    setupFunc(engine.Global[ctorName], type.ToHostType(engine), names.Distinct());
}

Here's an example. Suppose your extension class looks like this:

public static class StringExtensions {
    public static void PrintBracketed(this string self) => Console.WriteLine("[{0}]", self);
    public static void PrintBracketed(this string self, string tail) => Console.WriteLine("[{0}{1}]", self, tail);
    public static void PrintBraced(this string self, string tail = "") => Console.WriteLine("{{{0}{1}}}", self, tail);
}

Here's how to install it and consume it from JavaScript:

AddPrototypeExtensions(engine, "String", typeof(StringExtensions));
engine.Execute(@"
    'foo'.PrintBracketed();       // output: [foo]
    'bar'.PrintBracketed('baz');  // output: [barbaz]
    'qux'.PrintBraced();          // output: {qux}
");

That's just one possible solution. Hopefully it gives you an idea of how the host and script engine can work together.

Good luck!

ClearScriptLib avatar Aug 10 '22 20:08 ClearScriptLib

many thanks, I'll try it,

coader avatar Aug 12 '22 01:08 coader

Hi @coader,

Please reopen this issue if you have additional questions related to this topic.

Thanks!

ClearScriptLib avatar Aug 17 '22 13:08 ClearScriptLib