Nowadays, there are a lot of talks about WebAssembly and how it would penetrate the front-end world. In fact, it has not yet. There are tones of articles about web assembly and how it works. I want to show you a use-case of running C# code in a browser.
There are several ways of how to do it. I would like to mention three of them.
- The first one is to use a Blazor Framework. It hides the complexity and gives a solid tool for building SPA applications (there is a very good article about WebAssembly and Blazor).
- The second way is to use a mono-wasm compiler and compile your code to a WASM file. It does Ahead of Time compilation and it works very well (there is an article about MONO and WASM and a good explanation of how mono compiles C# into wasm).
- The third scenario is to run .Net libraries in a browser, as a Blazor framework does, but without Blazor. As was mentioned in the article above, there is a very good explanation of how Blazor works. Furthermore, it tells that for running .net assemblies we need a mono-compiled version of the .NET Runtime which was compiled to a WASM module to execute .NET Standard modules. Is it overhead? Of course, there are some lacks. To be honest, I don’t know. We will see ;).
Another question is: “Do we really need it?”. The 3rd scenario might be useful for someone who wants to upgrade a front-end app and play with it. Nevertheless, I recommend using AoT compiled wasm file with React, Angular or Vue applications. Blazor framework can be even used if a project has just started.
Here is an example of how to use this approach. There is a react based front-end application, which is hosted by NodeJs (of course, there are no talks about Blazor). Users can load any .Net standard modules(library assemblies) and retrieve metadata from them or even call some methods and use results for configuring higher modules. Assemblies represent small modules with some logic and certain responsibility (Ex.: calculation of material strength). There are some dynamic behaviors and reflections that’s why developers can’t use AOT compilation for it. Pass and retrieve assemblies, and relative data through Http is a heavy payload. Assemblies shouldn’t be saved somewhere, they should be extracted and executed, that’s it.
Before going forward I want to define a task: Recreate the example case mentioned above.
Let’s create a web application:
dotnet new web -n playDllAndWasm
Next, create the “wwwroot” folder within index.html file, and modify the Startup.cs file as shown below.
Furthermore, We need to add precompiled WASM .Net runtime (mono-wasm) and the mono script (mono.js) to run it. You can get them from the mono-wasm GitHub page. There is also a link to Binary releases. Get a packager and use it to generate the whole bunch of libraries for running .Net module. I have done all these, but here is my suggestion: if you want to play around and do not kill yourself, you can easily clone this demo project repo.
Note: If you want to play with mono-wasm AOT compilation you have to deal with packager. There are might be some changes, as it is under development.
After that, let’s create a “managed” folder which will contain all .Net assemblies. Put there the first and the most important assembly — “mscorlib.dll”. We need it to run assemblies because it is a Multilanguage Standard Common Object Runtime Library. Go forward and add an index.html file to the “wwwroot” folder and modify it as it is shown below.
What does the code above? The first script tag creates an empty object “Module” and declares only one method where we can place calls to the MONO instance. Through the MONO instance, developers can configure and act with the .Net world. The second script tag loads mono.js file that contains commands which load and run mono.wasm. In addition, it triggers “onRuntimeInitialized” when everything is initialized (for ex.: MONO instance)and prepared to work. Run and see what it does.
It shows only “Hello world!”. However, if you open a dev console you’ll see some logs from the mono. It tells that the runtime environment is ready which consequently shows that we can continue the development.
Next, we need to create our first, but not last, .Net standard module and run it. Let’s execute the next command:
dotnet new classlib -n SomeComputing
There will be only one class with the code below:
Index.html should be modified. Now it needs some extra libraries to be able to point what to call, and of course our “SomeComputing” library. Check out the changes:
A function above initializes .Net WebAssembly bindings and points to a method which should be called. If it runs, the dev console will show you the result of method execution.
A common way of calling some .Net functionality was implemented above. It could be done by mono-wasm AoT compilation and got only one WASM file, without any .Net assembly dependencies. For continuing the development, the front-end needs some extra libraries. Create several new netstandard projects:
dotnet new classlib -n CommonLibrary
dotnet new classlib -n ComputeFibonacci
dotnet new classlib -n ComputeDateTimes
A “CommonLibrary” project has only one .cs file with an interface.
The “IExecutable” interface is an assembly’s entry point. The “Execute” method is a common declaration of methods that will be executed on a front-end side. “ComputeFibonacci” and “ComputeDateTimes” projects will depend on the “CommonLibrary” project. Next, add a new class to SomeComputing project that will load assemblies and run them.
ComputeFibonacci and ComputeDateTimes contain only one class that implements the“IExecutable” interface.
These two projects should be built and their assemblies should be taken for loading and executing. Ohh right, I think it’s time for a demo.
This technology is pretty young. It has many issues but it also shows potential. It is a fast, safe, light, portable and open standard. In this article, I wanted to show one of the “use cases” of this technology. This article is more about encouraging. In my opinion, we will see some new libraries or even frameworks which will be based on WASM. There is also a good news about the fourth language for the Web. So, don’t waste time, jump on a train :).
Thanks Niki for awesome illustration.