canhorn / EventHorizon.Blazor.TypeScript.Interop.Generator

This project is a Blazor Interop C# Generator, has a sample against the BabylonJS library.
https://wonderful-pond-05f7b3b10.azurestaticapps.net/
MIT License
133 stars 19 forks source link

[Question] How to access JsObject from C# ? #7

Open redradist opened 4 years ago

redradist commented 4 years ago

Hi,

I have found this project and it is very exiting, but I have not found how to access JsObject reference from C# ?

Also it would be nice if this access was made with https://github.com/RemiBou/BrowserInterop API as from my perspective simplest interaction with Browser, - it will get single JsObjectRef object for different projects ;)

canhorn commented 4 years ago

Hello, I am glad you find this project existing. :)

This project is more for generating the C# from a TypeScript definition file. Abstracting away JavaScript instruction calls, like new, calling functions, or getting/setting properties.

For https://github.com/RemiBou/BrowserInterop, that is a little different from what this project does, that project give access to the browser provided JavaScript APIs.

This project creates a C# abstraction to a libraries API, for something like BabylonJS it makes it easier to create a game from C# with very little JavaScript needed.

The the Sample Solution for this repository includes a .NET Console application that will generate a small subset of APIs for BabylonJS.

Using the generated API project, a Blazor WASM site can then use the classes for an easier API to using BabylonJS, here is an example of a deployed website: https://wonderful-pond-05f7b3b10.azurestaticapps.net/

As for not using BrowserInterop, that does not supply the necessary functionality to interface with common JavaScript instructions. I had to create another project EventHorizon.Blazor.Interop that has the common instruction set for javascript, like creating a "new" object, or calling a function with arguments. EventHorizon.Blazor.Interop also has a simple caching layer that makes transferring the data between C# and JavaScript slimmer for performance.

This comment is kind of long, So if you want me to clarify anything I will try my best.

Cody

redradist commented 4 years ago

@canhorn

Hello, I am glad you find this project existing. :)

This project is more for generating the C# from a TypeScript definition file. Abstracting away JavaScript instruction calls, like new, calling functions, or getting/setting properties.

For https://github.com/RemiBou/BrowserInterop, that is a little different from what this project does, that project give access to the browser provided JavaScript APIs.

This project creates a C# abstraction to a libraries API, for something like BabylonJS it makes it easier to create a game from C# with very little JavaScript needed.

The the Sample Solution for this repository includes a .NET Console application that will generate a small subset of APIs for BabylonJS.

Using the generated API project, a Blazor WASM site can then use the classes for an easier API to using BabylonJS, here is an example of a deployed website: https://wonderful-pond-05f7b3b10.azurestaticapps.net/

As for not using BrowserInterop, that does not supply the necessary functionality to interface with common JavaScript instructions. I had to create another project EventHorizon.Blazor.Interop that has the common instruction set for javascript, like creating a "new" object, or calling a function with arguments. EventHorizon.Blazor.Interop also has a simple caching layer that makes transferring the data between C# and JavaScript slimmer for performance.

This comment is kind of long, So if you want me to clarify anything I will try my best.

Cody

I cannot actually get why BrowserInterop do not provide needed functionality ...

I have successfully created wrapper around GooglePay https://github.com/redradist/BlazorGooglePay using JsObjectRef provided by BrowserInterop

I have opened EventHorizon.Blazor.Interop https://github.com/canhorn/EventHorizon.Blazor.Interop/blob/main/EventHorizon.Blazor.Interop.Sample/wwwroot/Bridge.js and as for me BrowserInterop provides more functionality https://github.com/RemiBou/BrowserInterop/wiki/Utility-methods

The issue is that Microsoft do not provide proper solution for interacting with JsObject-s and this library provides nice API for registering and unregistering JsObject and interaction with it ...

We as community should choose proper solution, but as I see each developer reimplement wheel ... wheel of BrowserInterop is very mature as for me ;)

canhorn commented 4 years ago

BrowserInterop does provided the functionality I needed, but it provides them as async, I wanted a way that would hide the async nature of the JSRuntime in a WASM environment.

EventHorizon.Blazor.Interop https://github.com/canhorn/EventHorizon.Blazor.Interop/blob/main/EventHorizon.Blazor.Interop.Sample/wwwroot/Bridge.js, is used by the sample, and just functionality I use for testing common scenarios.

The JS bridge here EventHorizon.Blazor.Interop , contains the full interop functionality used when interfacing with objects.

Here is an example API generated using this project: Engine.cs This is the Engine.ts class from the BabylonJS game framework, the usage of this simplifies to: var engine = new Engine( canvas, true ); But then that is what this project can generate, using this project you can generate a API over BabylonJS: https://github.com/canhorn/EventHorizon.Blazor.TypeScript.Interop.Generator/tree/main/Sample/_generated/EventHorizon.Blazor.BabylonJS.WASM

redradist commented 4 years ago

BrowserInterop does provided the functionality I needed, but it provides them as async, I wanted a way that would hide the async nature of the JSRuntime in a WASM environment.

EventHorizon.Blazor.Interop https://github.com/canhorn/EventHorizon.Blazor.Interop/blob/main/EventHorizon.Blazor.Interop.Sample/wwwroot/Bridge.js, is used by the sample, and just functionality I use for testing common scenarios.

The JS bridge here EventHorizon.Blazor.Interop , contains the full interop functionality used when interfacing with objects

You could just wrap around async and provide user .Wait() ?

canhorn commented 4 years ago

I did try that on a few of my prototypes. It complicated the usage, added overhead, and in most cases creates a deadlock. I choose this usage, so the generated APIs would function like the Javascript it was generated from.