BlazorBindGen 0.0.3.7
dotnet add package BlazorBindGen --version 0.0.3.7
NuGet\Install-Package BlazorBindGen -Version 0.0.3.7
<PackageReference Include="BlazorBindGen" Version="0.0.3.7" />
paket add BlazorBindGen --version 0.0.3.7
#r "nuget: BlazorBindGen, 0.0.3.7"
// Install BlazorBindGen as a Cake Addin #addin nuget:?package=BlazorBindGen&version=0.0.3.7 // Install BlazorBindGen as a Cake Tool #tool nuget:?package=BlazorBindGen&version=0.0.3.7
BlazorBindGen
A binding generator for JS, Call any JS function or property in <b>Blazor Wasm and Server (Including MAUI hybrid)</b> without writing JS wrappers.
Why Use BlazorBindGen
- very tiny Overhead ~13kb
- No need to write JS wrappers
- Support for Callbacks
- Write JS code in C#
- WASM and Server Supported
- automatic memory management
Installation
Use Nuget Package Manager or .Net CLI
dotnet add package BlazorBindGen
Initialize BindGen
- on top of razor page add Import statements
@inject IJSRuntime runtime
@using BlazorBindGen
@using static BlazorBindGen.BindGen
@using JSCallBack=System.Action<BlazorBindGen.JObjPtr[]>; //optional Typedef
- Intitialize the BindGen
protected override async Task OnInitializedAsync()
{
await base.OnInitializedAsync();
await InitAsync(runtime);
}
//on Server
protected override async Task OnAfterRenderAsync(bool firstRender)
{
if (!firstRender)
return;
await InitAsync(runtime);
}
Binding Samples
<b>
→ Js code is for explaination purpose only , you do not need to write js code anywhere.<br>
→ On Server use Async Version of functions (non async functions will throw PlatformNotSupportedException
)</b>
Import JS libaries when ever you want in C#
// js equivalent
await import("https://unpkg.com/ml5@latest/dist/ml5.min.js");
//c# side
await ImportAsync("https://unpkg.com/ml5@latest/dist/ml5.min.js");
// js equivalent, importing modules
let ml5=await import("https://unpkg.com/ml5@latest/dist/ml5.min.js");
//c# side
var ml5Ptr=await ImportRefAsync("https://unpkg.com/ml5@latest/dist/ml5.min.js");
Constructor Calls
//js side
var audio=new Audio(param);
//c# side code
var_audio=Window.Construct("Audio",param); /* js reference to Audio Player */
Function Calls
//js equivalent
alert("Hello");
//code to call alert in C#
Window.CallVoid("alert","hello");
Share JS object References
//js equivalent
var video = document.querySelector("#videoElement");
//here document is property of window , and dcument has function querySelector
//c# code
var video = Window["document"].CallRef("querySelector", "#videoElement");
//["documemnt"] will return reference to Property document of window , another way to write it is
JObjPtr video = Window.PropRef("document").CallRef("querySelector", "#videoElement");
//CallRef function calls JS function and Returns a reference to it, instead of whole object
Get Set Properties
// equivalent js code
var ctx = c.getContext("2d");
var grd = ctx.createRadialGradient(75, 50, 5, 90, 60, 100);
ctx.fillStyle = grd;
//c# side
var ctx=canvas.CallRef("getContext","2d");
var grad = ctx.CallRef("createLinearGradient", 0,0,400,0);
ctx.SetPropRef("fillStyle",grad);
//assign a reference to grad(a JobjPtr reference) to property fillStyle of canvas context
Mapping JS property to C#
//js
var audio=new Audio();
audio.currentTime=6; //set
console.log(audio.currentTime); //get
//c# equivalent
JObjPtr _audio=Window.Construct("Audio"); /* js reference to Audio Player */
public double CurrentTime
{
get => _audio.PropVal<double>("currentTime");
set => _audio.SetPropVal("currentTime", value);
}
Map Js Callback to C# event
//js equivalent
var audio=new Audio();
audio.onloadeddata=()=>{ console.log("loaded"))};
//cs equivalent
{
var _audio=Window.Construct("Audio"); /* js reference to Audio Player */
_audio.SetPropCallBack("onloadedmetadata", (_) => OnLoadedMetaData?.Invoke(this));
}
public delegate void LoadedMetaDataHandler(object sender);
public event LoadedMetaDataHandler OnLoadedMetaData;
Be sure to check out sampleApp for more examples
Example (using ML5 in C# only)
@page "/ml5"
@using BlazorBindGen
@using static BlazorBindGen.BindGen
@using JSCallBack=System.Action<BlazorBindGen.JObjPtr[]>; //optional only needed to simplify callback type name
@inject IJSRuntime runtime
@if (isLoaded)
{
<input type="text" class="bg-dark text-white border-light" @bind="predictText" placeholder="write review here " style="font-size:18px"/>
<button class="btn btn-primary" id="mbtn" @onclick="Predict">Predict</button><br /><br />
if(score>0)
{
<div class="alert alert-primary">
<p>Review: @GetEmoji() <br />Score: @score</p>
</div>
}
}
else
{
<div class="alert alert-warning">
Fetching Movie Review Dataset (~16 MB)
</div>
}
@code
{
JWindow win;
public JObjPtr sentiment;
string predictText;
bool isLoaded = false;
double score;
protected override async Task OnInitializedAsync()
{
await base.OnInitializedAsync();
await Init(runtime);
win = Window;
await ML5Init();
}
async Task ML5Init()
{
await Import("https://unpkg.com/ml5@latest/dist/ml5.min.js");
Console.Clear();
var ml5 = win["ml5"];
sentiment = ml5.CallRef("sentiment", "movieReviews", (JSCallBack)OnModelLoaded);
}
void Predict()
{
var v = sentiment.Call<Score>("predict", predictText);
score=v.score;
StateHasChanged();
}
void OnModelLoaded(params JObjPtr[] args)
{
isLoaded = true;
StateHasChanged();
}
string GetEmoji()
{
if (score > 0.7)
return "😀";
else if (score > 0.4)
return "😐";
else
return "😥";
}
record Score(double score);
}
Experimentation Auto Bind Generator for WASM
Above example binding could also be generated with Source Generator for WASM .
using BlazorBindGen.Attributes;
namespace SampleApp.JSBinding
{
[JSWindow] // represents JS Window class
public static partial class DomWindow
{
[JSProperty]
private static ML5 ml5; // refers to window.ml5 prop js side
}
[JSObject("https://unpkg.com/ml5@latest/dist/ml5.min.js")]
public partial class ML5
{
[JSFunction("sentiment")]
public partial Sentiment Sentiment(string modelName,OnModelLoadHandler onModelLoad);
[JSCallback]
public delegate void OnModelLoadHandler();
[JSConstruct("p5")]
public partial Sentiment Construct();
}
[JSObject]
public partial class Sentiment
{
[JSFunction("predict")]
public partial Score Predict(string text);
}
public record Score(double score);
}
see usage here
Warning
- BlazorBindGen Api is subject to change, API is not stable.
- Note: Blazor Server requires use of Async functions otherwise UI thread will be blocked by it or alternatively you can call BindGen functions on different thread <br/> #issue.
Product | Versions Compatible and additional computed target framework versions. |
---|---|
.NET | net6.0 is compatible. net6.0-android was computed. net6.0-ios was computed. net6.0-maccatalyst was computed. net6.0-macos was computed. net6.0-tvos was computed. net6.0-windows was computed. net7.0 was computed. net7.0-android was computed. net7.0-ios was computed. net7.0-maccatalyst was computed. net7.0-macos was computed. net7.0-tvos was computed. net7.0-windows was computed. net8.0 was computed. net8.0-android was computed. net8.0-browser was computed. net8.0-ios was computed. net8.0-maccatalyst was computed. net8.0-macos was computed. net8.0-tvos was computed. net8.0-windows was computed. |
-
net6.0
- Microsoft.AspNetCore.Components.Web (>= 6.0.30)
NuGet packages
This package is not used by any NuGet packages.
GitHub repositories
This package is not used by any popular GitHub repositories.