.NET MAUI Blazor Hybrid で作成された、SQLite3 を DB のバックエンドとして利用する Pokedex アプリ。
厳密に言うと、このプロジェクトでは Razor Components を Blazor custom elements として扱っていません。 Razor Components を root component として登録し、JavaScript から呼び出せるようにしています。
ref: Use Razor components in JavaScript apps and SPA frameworks
制約事項や特徴などが Blazor custom elements と似通っているため、ここでは Blazor custom elements として扱っています。
.NET MAUI Blazor Hybrid では、BlazorWebView
における RootComponents
プロパティに登録することで、Blazor のルートコンポーネントを指定することが出来ます。
テンプレートから作成された .NET MAUI Blazor Hybrid アプリケーションでは、MainPage.xaml
に BlazorWebView
コンポーネントが配置されており、RootComponents
プロパティに RootComponent
が配置されています。
これに習い、コードビハインドから RootComponents
プロパティに RootComponent
を登録します。
以下のコードは、FetchPokemon
コンポーネントを fetch-pokemon-js
という名前で登録する例です。
MainPage.xaml.cs
// https://learn.microsoft.com/en-us/dotnet/api/microsoft.aspnetcore.components.web.jscomponentconfigurationextensions.registerforjavascript?view=aspnetcore-8.0
using Microsoft.AspNetCore.Components.Web; // Add this
...
public MainPage()
{
InitializeComponent();
// Add this
blazorWebView.RootComponents.RegisterForJavaScript<Components.JSInterop.FetchPokemon>("fetch-pokemon-js");
}
これにより、Blazor 環境下の JavaScript アプリケーションから、fetch-pokemon-js
という名前で FetchPokemon
コンポーネントを呼び出すことが出来るようになります。
see: @pokedex-dotnet-react/interop-mauiblazor
see: @pokedex-dotnet-vue/interop-mauiblazor
RootComponent として登録された Razor Components で公開されているメソッドを JavaScript から呼び出すことが出来ます。
また EventCallback
を利用して、.NET から JavaScript の関数を呼び出すことが出来ます。
JavaScript へ .NET のメソッドを公開するには、JSInvokable
属性を利用します。
このプロジェクトでは、FetchPokemon
コンポーネントで FetchPokemons
メソッドを JSInvokable
属性を付与して公開しています。
FetchPokemon.razor.cs
using Microsoft.JSInterop;
...
[JSInvokable]
public async Task<Pokemon[]> FetchPokemons()
{
if (DataSource == null) return Array.Empty<Pokemon>();
var dbHelper = new SqliteConnectionWrapper(() => DataSource);
var pokemons = await PokedexDotnet.Shared.Usecases.QueryPokemon.FetchPokemons(dbHelper);
return pokemons;
}
このメソッドは、JavaScript から dotnetRef.invokeMethodAsync("FetchPokemons")
として呼び出すことが出来ます。
上記の呼び出しで dotnetRef
変数が使用されています。
これは、BlazorWebView
における RootComponents
プロパティに登録されたコンポーネントに対して、JavaScript からアクセスするための参照です。
C# 側では DotNetObjectReference として提供されています。
このプロジェクトでは、BaseComponent
という実装するコンポーネントの基底クラスを作成し、DotNetObjectReference
を保持するプロパティや、JavaScript 側にコールバックで参照を渡すための実装を提供しています。
また DotNetObjectReference
は .NET のインスタンスメソッドを呼び出すことに利用されるため、このプロジェクトでは Razor Components には static メソッドを実装していません。
ref: Invoke an instance .NET method
.NET から JavaScript の呼び出しは、EventCallback に登録されたコールバックを実行することで行います。
このプロジェクトでは、BaseComponent
コンポーネントで、コンポーネントのレンダリングが完了した際に、対象のコンポーネントの参照を JavaScript に渡すために利用しています。
BaseComponent.cs
using Microsoft.AspNetCore.Components;
using Microsoft.JSInterop;
...
[Parameter] public EventCallback<DotNetObjectReference<T>> OnComponentInitializedCb { get; set; }
.NET MAUI Blazor Hybrid から React / Vue.js アプリケーションのような、UI を伴う JavaScript アプリケーションを呼び出すことが出来ます。
ref: JavaScript libraries that render UI
このプロジェクトでは、BlazorWebView の RootComponent として呼び出される ViewRoot.razor
に空の div
要素を配置し、その div
要素に対して JavaScript アプリケーションをマウントすることで、JavaScript アプリケーションを呼び出しています。
例えば @pokedex-dotnet-react/entry-mauiblazor のビルド成果物を、wwwroot/js
ディレクトリに配置し、IJSRuntime.InvokeAsync
メソッドを利用して、モジュールの読み込みと React アプリケーションのマウント関数の実行を行っています。
これは Vue.js のアプリケーションでも同様です。
JavaScript から呼び出される Blazor custom elements は、Blazor のコンポーネントとして実装されているため、Blazor のデバッグ機能を利用することが出来ます。
VS Code などからデバッグ実行を行い、ブレークポイントを設定することで、Blazor custom elements のコードをデバッグすることが出来ます。
BlazorWebView 上で実行している JavaScript のエラーなどは、ブラウザのデベロッパーツールなどを利用してデバッグすることが出来ます。 以下の Microsoft Learn ドキュメントを参考にしてください。
ref: Use browser developer tools with ASP.NET Core Blazor Hybrid