Open DavidBal opened 1 year ago
Hi @DavidBal,
Host objects in ClearScript currently don't support Symbol.dispose
; in fact, V8 defines no such symbol. However, a relevant proposal appears to be in flight, and TypeScript is evidently ahead of the curve.
Anyway, assuming that Symbol.dispose
is available, you could do something like this:
dynamic setupFunc = engine.Evaluate(@"(
function (host, IDisposable) {
Object.defineProperty(Object.getPrototypeOf(host), Symbol.dispose, {
get() {
const disposable = host.asType(IDisposable, this);
return disposable ? () => disposable.Dispose() : undefined;
}
});
}
)");
setupFunc(new HostFunctions(), typeof(IDisposable).ToHostType(engine));
With this setup in place, most host objects will support Symbol.dispose
. We say "most" because the code above adds Symbol.dispose
only to the HostFunctions
prototype, which is shared among all "normal" host objects. There are other prototypes specifically for delegates and dynamic objects, for which a similar technique can be used if necessary.
We'll keep an eye on the proposal and add full support if and when it's incorporated into the JavaScript standard.
Good luck!
Hi again,
Here's a more complete solution:
dynamic setupFunc = engine.Evaluate(@"(
function (obj, host, IDisposable) {
Object.defineProperty(Object.getPrototypeOf(obj), Symbol.dispose, {
get() {
const disposable = host.asType(IDisposable, this);
return disposable ? () => disposable.Dispose() : undefined;
}
});
}
)");
var host = new HostFunctions();
var disposable = typeof(IDisposable).ToHostType(engine);
setupFunc(host, host, disposable);
setupFunc(new Action(() => {}), host, disposable);
setupFunc(new PropertyBag(), host, disposable);
This should set up Symbol.dispose
support for all host objects and types.
Cheers!
Hi,
thank you that works great.
Here is my full implementation, should someone else have the same problem:
dynamic setupDisposeFunc = scriptEngine.Evaluate("""
(
function (obj, host, IDisposable) {
Symbol.dispose ??= Symbol("Symbol.dispose");
Object.defineProperty(Object.getPrototypeOf(obj), Symbol.dispose, {
get() {
const disposable = host.asType(IDisposable, this);
return disposable ? () => disposable.Dispose() : undefined;
}
});
}
)
""");
dynamic setupAsyncDisposeFunc = scriptEngine.Evaluate("""
(
function (obj, host, IAsyncDisposable) {
Symbol.asyncDispose ??= Symbol("Symbol.asyncDispose");
Object.defineProperty(Object.getPrototypeOf(obj), Symbol.asyncDispose, {
get() {
const disposable = host.asType(IAsyncDisposable, this);
return disposable ? () => disposable.DisposeAsync() : undefined;
}
});
}
)
""");
HostFunctions host = new HostFunctions();
object disposable = typeof(IDisposable).ToHostType(scriptEngine);
object asyncDisposable = typeof(IAsyncDisposable).ToHostType(scriptEngine);
setupDisposeFunc(host, host, disposable);
setupDisposeFunc(new Action(() => { }), host, disposable);
setupDisposeFunc(new PropertyBag(), host, disposable);
setupAsyncDisposeFunc(host, host, asyncDisposable);
setupAsyncDisposeFunc(new Action(() => { }), host, asyncDisposable);
setupAsyncDisposeFunc(new PropertyBag(), host, asyncDisposable);
Best regards, David
Hi ClearScript Team,
in the recent update of TypeScript the using statement was added. https://devblogs.microsoft.com/typescript/announcing-typescript-5-2/#using-declarations-and-explicit-resource-management
The JavaScript for this feature looks something like this:
Is there any way we can map this call to CSharp?
Thanks in advance.
Best regards, David