入門者向け

Blazor HybridとBlazor Web AppのUIをRCLで共通化する手順

blazor-hybrid-maui-rcl

Blazor Hybrid は、iOS と Android で動くネイティブアプリとデスクトップアプリの UI や一部ロジックを共通化できるものです。

さらに、RCL(Razor Class Library)を使うことで、Web の UI とも共通化することができます。

ただし、RCL を使った Web との共通化については具体的な手順が書かれておらず、いろいろと調べながら作業する必要があり、少し苦戦してしまいました。

そこで本記事では誰でも簡単にできるよう、ゼロから作成する手順について解説していきます。

Blazor Hybrid の環境構築については、この記事では割愛します。はじめての人は、公式ドキュメントもあわせて読んでみるといいかもしれません。

Blazor Hybrid と Blazor Web App の UI を RCL で共通化する手順

完成形は GitHub リポジトリで公開しています。

.NET 8 が必要なのでまだインストールしていない人は、インストールしておいてください。

以降で作成するプロジェクト名は例なので、任意の名称で構いません。

Blazor Web App プロジェクトの作成

まず初めに、Blazor Web App のプロジェクトを新規に作成します。

blazor-hybrid-maui-rcl

プロジェクト名は BlazorHybrid.Web とし、ソリューション名からは .Web を削除します。

blazor-hybrid-maui-rcl

今回は .NET 7 までで言うところの Blazor Server の挙動にしたいと思うので、以下のような構成でプロジェクトを作成します。

blazor-hybrid-maui-rcl

RCL プロジェクトの作成

続いて RCL プロジェクトを作成していきます。

「Razor クラスライブラリ」という名前のテンプレートがあるのでそちらを選択し、.NET 8 で作成してください。

プロジェクト名は任意ですが、今回は BlazorHybrid.RCL にします。

blazor-hybrid-maui-rcl

これはやらなくても問題ありませんが、使わない初期ファイルが含まれているので、削除するとスッキリします。

差分はこちらにあるので、参考にしてください。

Blazor Hybrid プロジェクトの作成

Blazor Hybrid は「.NET MAUI Blazor アプリ」という名前のテンプレートがあるので、そちらを選択し、.NET 8 で作成してください。

プロジェクト名は任意ですが、今回は BlazorHybrid.Maui にします。

blazor-hybrid-maui-rcl

これで1つのソリューションに3つのプロジェクトが追加されました。

Web の Razor コンポーネントを RCL に移動

Web の UI まわりを RCL に移動するおおまかな手順は以下のとおりです。

  1. Web プロジェクトに RCL プロジェクトの参照を追加する
  2. Web の Razor コンポーネントを RCL に移動する
  3. RCL の _Imports.razor を更新する
  4. Web の Program.cs を少し更新する

上記の差分はこちらから確認できるので、参考にしてください。

1点、Web の Program.cs を少し更新するところについて解説します。

Program.cs
app.MapRazorComponents<App>()
    .AddInteractiveServerRenderMode()
    .AddAdditionalAssemblies([typeof(BlazorHybrid.RCL._Imports).Assembly]);

追加しているのは最後の1行ですが、これがないとトップページが見つからないエラーになります。

移動先である RCL プロジェクトのアセンブリを追加する必要があり、アセンブリ名が取得できればファイルは何でもいいのですが、今回は _Imports.razor のファイルを指定しました。

Web の静的資産を RCL に移動

Razor コンポーネントを移動しただけでも動きますが、wwwroot フォルダに置くような静的資産も RCL に移動できます。

差分はこちらから確認できるので、参考にしてください。

なお、app.cs は Blazor Hybrid 側と少し内容が異なるので、共通化するのであればマージする必要があります。

GitHub の差分上は移動していますが、最終的に元に戻しました。

また、Routes.razor を消し忘れていたので別の差分で消しています。

1点、App.razor の差分について解説しておきます。

Components/App.razor
<link rel="stylesheet" href="_content/BlazorHybrid.RCL/bootstrap/bootstrap.min.css" />
<link rel="stylesheet" href="app.css" />

プロジェクト外のファイルを参照する場合は、_content/{PACKAGE ID/ASSEMBLY NAME}/{PATH}/{FILE NAME}の形式で記載する必要があります。

今回の場合は、bootstrap.min.css は RCL に移動するため上記の形式となり、app.css は Web プロジェクトに残すためそのままにします。

ここまで変更したら、デバッグ実行して動作に問題がないか調べてみましょう。

blazor-hybrid-maui-rcl

Maui プロジェクトの資産を RCL に移動

Maui プロジェクトから RCL プロジェクトを参照すると、ほとんどの Razor コンポーネントと静的資産が共有できるので、Maui プロジェクトからはファイルを削除します。

差分はこちらから確認できるので、参考にしてください。

Web と同様、app.cs は RCL に移動する必要はありません。

変更点の差分にもありますが、MainPage.xaml の中で Routes.razor を参照しているところがあり、そのファイルは RCL に移動するので、参照先の変更が必要な点に注意してください。

rendermode を Web 側から指定

ここまでで Maui プロジェクトもほぼ動く状態になりましたが、Counter.razor で指定されている rendermode が Blazor Hybrid に対応していません。

実行して /counter のページを開くと以下のエラーが出ます。

Cannot supply a component of type ‘BlazorHybrid.RCL.Components.Pages.Counter’ because the current platform does not support the render mode ‘Microsoft.AspNetCore.Components.Web.InteractiveServerRenderMode’.

このエラーを解消するには rendermode を消せばよいのですが、Web から参照するときには rendermode を指定しないと、Click me のボタンを押してもカウントが増えません。

そこで、ページ単位ではなく、より上位の層にあるコンポーネント単位で指定するよう修正します。

差分はこちらから確認できるので、参考にしてください。

今回はアプリ全体で @rendermode="InteractiveServer"を指定しましたが、ページ単位で切り替えたい場合はまた別のアプローチが必要になります。

また、通常は HeadOutlet コンポーネントでも同じ rendermode を指定する必要があります。

ここまで修正すると、Maui 側でも動作確認ができます。

以下は Windows アプリで実行した場合のイメージです。

blazor-hybrid-maui-rcl

最後に

Blazor Hybrid と Blazor Web App の UI を RCL で共通化する手順について解説しました。

いきなりネイティブアプリから作るとビルドや配布が面倒だったりするので、まずは Web で作って操作感を見ることができるのはよさそうですよね。

自分の手でゼロから作成するのはちょっと面倒なので、できれば公式でテンプレート化してほしいところです。

GitHub リポジトリからクローンしてくるのでも問題ありませんが、この記事を見ながら作業すれば簡単にできるはずなので、ぜひ試してみてください。

Blazor の書籍も好評発売中!
blazor-book

入門編から EC サイトを作る応用編まで、Blazor の本を3冊執筆しました。

私が1年以上かけて学習した内容をすべて詰め込んでいるので、さらにステップアップしたい方はぜひご覧ください。