Open mmarinchenko opened 1 year ago
If I'm not mistaken, this particular set of API is now discouraged as it is not performant, and it is best to use JSImport/JSExport attributes, which Uno supports properly. Are you able to use this approach instead?
Issue background
We are experimenting with cross-platform 3D visualization running inside Uno.WinUI shell. This issue covers WebAssebly case, so if we forget about other platforms, some kind of JavaScript 3D engine, such as Babylon.js, could be used as a workaround. But ideally, we would like to go Uno-way as much as possible, so the 3D engine should be cross-platform and run on .NET.
One potentially possible third-party option is Plain Concepts' Evergine. Like most Blazor-related libraries, Evergine uses Microsoft.AspNetCore.Components.WebAssembly package, which, in turn, relies on Microsoft.JSInterop to interact with JavaScript API. As a result, we basically need a JavaScript infrastructure that would be compatible with both Uno.Wasm.Bootstrap and Microsoft.JSInterop.
Please note that Evergine is just an example to provide the issue background. We are not part of Evergine team or any other Plain Concepts affiliate. Feel free to provide us with any other cross-platform .NET 3D visualization solution compatible with Uno, if you have one.
Why might this be important for Uno?
Number of .NET libraries, ported to WebAssembly, is constantly growing.
Some of them require interaction with JavaScript API. Microsoft.JSInterop, for obvious reasons, is used by default unless they assume compatibility specifically with Uno.
Some of them have a proprietary license (like Evergine still has) and cannot be modified by third party. The lack of compatibility between the two technologies may slow down Uno/.NET adoption in WebAssembly world.
Our investigations
dotnet.js bundled with Uno has the following functions (see 0004-restore-jsinterop-invokejsunmarshalled.patch):
The first mentioned function invokes
Blazor._internal.invokeJSFromDotNet(...)
which isn't present in Uno. It could be added in an additional JS script as EmbeddedResource, but the problem is that theBlazor._internal
object, on the other hand, is present in Uno and written in a non-extensible way: it uses direct assignment of anonymous object, which overwrites any additions.We've tried to customize this code to add
Blazor._internal.invokeJSFromDotNet(...)
, but it isn't clear to us which implementation should be used here. The ASP.NET Core implementation (as of version 6.0) usesDotNet.jsCallDispatcher
object, which is also present in Uno, but has a completely different implementation (includingDotNet.jsCallDispatcher.findJSFunction(...)
which is invoked by the second mentioned function from dotnet.js bundled with Uno).Neither blazor.webassembly.js nor Microsoft.JSInterop.js can be used directly with Uno, because this breaks everything. So what should we do?
Additional notes
https://github.com/mmarinchenko/UnoWasmApp repository contains empty Uno application with Wasm head. Last commit adds the Microsoft.AspNetCore.Components.WebAssembly package and the
Microsoft.AspNetCore.Components.WebAssembly.Hosting.WebAssemblyHostBuilder.CreateDefault()
call to reproduce the issue. No other changes were made, except for some minor format and package version fixes.P.S. This could be a success story in the future if we solve this issue!