ASP.NET Core Blazor Hybrid で Razor コンポーネントを再利用する

注意

これは、この記事の最新バージョンではありません。 現在のリリースについては、この記事の .NET 8 バージョンを参照してください。

警告

このバージョンの ASP.NET Core はサポート対象から除外されました。 詳細については、「.NET および .NET Core サポート ポリシー」を参照してください。 現在のリリースについては、この記事の .NET 8 バージョンを参照してください。

重要

この情報はリリース前の製品に関する事項であり、正式版がリリースされるまでに大幅に変更される可能性があります。 Microsoft はここに示されている情報について、明示か黙示かを問わず、一切保証しません。

現在のリリースについては、この記事の .NET 8 バージョンを参照してください。

この記事では、Blazor Hybrid アプリの Web および Web Views 用 Razor コンポーネントを作成および整理する方法について説明します。

Razor コンポーネントは、複数のホスティング モデル (Blazor WebAssembly、Blazor Server、および Blazor Hybrid の Web View) と複数のプラットフォーム (Android、iOS、Windows) で動作します。 各ホスティング モデルとプラットフォームには、コンポーネントで利用できる固有の機能がありますが、複数のホスティング モデルとプラットフォームで実行されるコンポーネントでは、次の例に示すように、固有の機能を個別に利用する必要があります。

  • Blazor WebAssembly では、同期 JavaScript (JS) 相互運用がサポートされています。これは、Blazor Server アプリ内、および Blazor Hybrid アプリの Web Views 内の厳密非同期 JS 相互運用通信チャネルではサポートされません。
  • Blazor Server アプリ内のコンポーネントは、Entity Framework データベース コンテキストなど、サーバー上でのみ使用できるサービスにアクセスできます。
  • BlazorWebView 内のコンポーネントは、ネイティブ デスクトップ機能とモバイル デバイス機能 (位置情報サービスなど) に直接アクセスできます。 Blazor Server アプリと Blazor WebAssembly アプリは、同様の機能を提供するために、外部サーバー上のアプリの Web API インターフェイスに依存する必要があります。

設計原則

複数のホスティング モデルとプラットフォームでシームレスに動作できる Razor コンポーネントを作成するには、次の設計原則に従います。

  • Razor クラス ライブラリ (RCL) に共有の UI コードを 配置します。RCL は、異なるホスティング モデルとプラットフォームで使用される再利用可能な UI を保持するために設計されたコンテナーです。
  • 固有の機能の実装は、RCL には配置しないでください。 RCL では、ホスティング モデルとプラットフォームで実装する抽象化 (インターフェイスと基底クラス) を定義します。
  • 固有の機能は、ホスティング モデルやプラットフォームごとにオプトインするようにしてください。 たとえば、Blazor WebAssembly では IJSInProcessRuntimeIJSInProcessObjectReference をコンポーネント内で最適化として使用することがサポートされていますが、これを使用するのは、すべてのホスティング モデルとプラットフォームでサポートされるユニバーサル IJSRuntime および IJSObjectReference 抽象化に依存した、条件付きキャストとフォールバックの実装を使用する場合に限定してください。 IJSInProcessRuntime の詳細については、「ASP.NET Core Blazor で .NET メソッドから JavaScript 関数を呼び出す」を参照してください。 IJSInProcessObjectReference の詳細については、「ASP.NET Core Blazor で JavaScript 関数 から .NET メソッドを呼び出す」を参照してください。
  • 全般的なルールとして、コンポーネントでの HTML スタイル設定には CSS を使用します。 最も一般的な用途は、アプリの外観の一貫性を確保することです。 ホスティング モデルやプラットフォームによって UI スタイルを変える必要がある場合は、CSS を使って異なるスタイルを設定します。
  • 一部の UI で、ターゲットのホスティング モデルやプラットフォームに追加のコンテンツや異なるコンテンツが必要な場合は、コンテンツをコンポーネント内でカプセル化し、DynamicComponent を使って RCL 内でレンダリングできます。 追加の UI は、RenderFragment インスタンスを介してコンポーネントに提供することもできます。 RenderFragment について詳しくは、「子コンテンツのレンダリング フラグメント」と「再利用可能なレンダリング ロジックのためのレンダリング フラグメント」を参照してください。

プロジェクト コードの編成

可能な限り、コードと静的コンテンツは Razor クラス ライブラリ (RCL) に配置してください。 各ホスティング モデルとプラットフォームは、RCL を参照し、Razor コンポーネントで必要となる可能性があるアプリのサービス コレクションに個々の実装を登録します。

各ターゲット アセンブリには、そのホスティング モデルやプラットフォームに固有のコードと、アプリのブートストラップに役立つコードのみを含めるようにしてください。

Blazor WebAssembly、Blazor Server、Web ビューそれぞれに Razor クラス ライブラリ (RCL) に対するプロジェクト参照があります。

固有の機能に抽象化を使用する

次の例は、ホスティング モデルとプラットフォームごとに、位置情報サービス用の抽象化を使用する方法を示したものです。

  • マップ上のユーザーの場所の位置情報データを取得するためにアプリによって使用される Razor クラス ライブラリ (RCL) では、MapComponentRazor コンポーネントによって ILocationService サービスの抽象化が挿入されます。
  • Blazor WebAssembly および Blazor Server プロジェクト用の App.Web では、ILocationServiceWebLocationService として実装されます。これは、Web API 呼び出しを使って位置情報データを取得するものです。
  • .NET MAUI、WPF、および Windows フォーム用の App.Desktop では、ILocationServiceDesktopLocationService として実装されます。 DesktopLocationService では、プラットフォーム固有のデバイス機能を使用して位置情報データが取得されます。

Razor クラス ライブラリ (RCL) で、MapComponent により ILocationService サービスが挿入されます。別途、App.Web (Blazor WebAssembly と Blazor Server のプロジェクト) によって ILocationService が WebLocationService として実装されます。別途、App.Desktop (.NET MAUI、WPF、Windows フォーム) によって ILocationService が DesktopLocationService として実装されます。

.NET MAUIBlazor のプラットフォーム固有コード

.NET MAUI での一般的なパターンは、プラットフォーム固有の実装を使った部分クラスを定義するなど、異なるプラットフォームごとに個別の実装を作成することです。 たとえば、次の図をご覧ください。CameraService 用の部分クラスが、CameraService.Windows.csCameraService.iOS.csCameraService.Android.cs、および CameraService.cs のそれぞれで実装されています。

CameraService 用の部分クラスが、CameraService.Windows.cs、CameraService.iOS.cs、CameraService.Android.cs、CameraService.cs のそれぞれに実装されています。

プラットフォーム固有の機能を他のアプリで使用できるクラス ライブラリにパックしたい場合は、前の例で説明したのと同様の方法に従い、Razor コンポーネント用の抽象化を作成することをお勧めします。

  • コンポーネントを Razor クラス ライブラリ (RCL) に配置します。
  • .NET MAUI クラス ライブラリから RCL を参照し、プラットフォーム固有の実装を作成します。
  • 使用元のアプリ内で、.NET MAUI クラス ライブラリを参照します。

次の例は、写真を整理するアプリでの、画像の概念を示したものです。

  • .NET MAUIBlazor Hybrid アプリでは、参照先の RCL から InputPhoto を使用します。
  • .NET MAUI アプリでは .NET MAUI クラス ライブラリも参照します。
  • RCL 内の InputPhoto は、RCL で定義された ICameraService インターフェイスを挿入します。
  • ICameraService 用の CameraService 部分クラス実装は、RCL を参照する .NET MAUI クラス ライブラリ (CameraService.Windows.csCameraService.iOS.csCameraService.Android.cs) 内にあります。

.NET MAUIBlazor Hybrid アプリでは、それが参照する Razor クラス ライブラリ (RCL) から InputPhoto を使用します。また、.NET MAUI でも .NET MAUI クラス ライブラリを参照します。RCL の InputPhoto により、その RCL で定義された ICameraService インターフェイスが挿入されます。ICameraService 用の CameraService 部分クラスの実装は .NET MAUI クラス ライブラリ (CameraService.Windows.cs、CameraService.iOS.cs、CameraService.Android.cs) にあり、その RCL を参照します。

例については、「Blazor Web App を使用して .NET MAUIBlazor Hybrid アプリを構築する」を参照してください。