共有UIコンポーネントの作成
次に、画像生成アプリに必要なUIコンポーネントを作成していきましょう。今回は、ImageGenerator.Sharedプロジェクトに共通のUIコンポーネントを実装します。
@injectアノテーション
まず、プロジェクトが生成されたときに作成される、デフォルトのコンポーネントを確認しておきましょう。ImageGenerator.SharedプロジェクトのPagesフォルダにあるHome.razorでは、次の通りシンプルなページが定義されています。
@page "/" @using ImageGenerator.Shared.Services @inject IFormFactor FormFactor ~後略~
このコンポーネントの先頭では、@usingアノテーションで名前空間が追加され、@injectアノテーションでFormFactorサービスが注入(インジェクション)されています。これは依存性注入(DI)と呼ばれる手法で、コンポーネントが直接サービスのインスタンスを作成するのではなく、フレームワークから提供されるサービスを利用できるようにするものです。FormFactorサービスについては、後ほど詳しく解説します。
コンポーネントの追加
では、画像生成アプリに必要な独自のコンポーネントを追加していきましょう。
まずは、画像生成ページを作成します。ソリューションエクスプローラーで、ImageGenerator.Sharedプロジェクト内のPagesフォルダを右クリックします。そして[追加]-[Razorコンポーネント]を選択し、名前をImageGeneration.razorにします。

生成されたファイルの先頭にある <h3>タグの行を削除して、代わりに次のコードを記述します。
@page "/generate" <PageTitle>画像生成</PageTitle> <h1>AI画像生成</h1> <div class="row"> <div class="col-md-6"> <div class="form-group"> <label for="prompt">プロンプト</label> <textarea id="prompt" class="form-control" @bind="prompt" rows="3" placeholder="生成したい画像の説明を入力してください"></textarea> </div> <div class="form-group mt-2 mb-4"> <button class="btn btn-primary" @onclick="GenerateImage" disabled="@isGenerating"> @if (isGenerating) { <span>生成中...</span> } else { <span>画像を生成</span> } </button> </div> </div> <div class="col-md-6"> @if ( !string.IsNullOrEmpty(imageUrl) ) { <div class="text-center"> <img src="@imageUrl" class="img-fluid rounded" style="max-width:100%;" /> </div> } </div> </div> @code { }
先頭の@pageアノテーションで、このコンポーネントのURLを、/generateとして定義しています。
画面のレイアウトとしては、Bootstrapのグリッドシステムを利用して、左右に分割した構造にしています。左側には、プロンプト入力用のtextarea(テキストエリア)とボタンを配置しています。textareaでは、@bindディレクティブで、C#のprompt変数と連携させています。ボタンには、@onclickディレクティブでイベントハンドラを設定し、isGenerating変数に応じてボタンの文字を切り替えています。通常は「画像を生成」で、画像生成中は「生成中...」になります。
右側は画像のエリアです。imageUrl変数に値がある場合のみ、生成された画像を<img>タグで表示します。
画像生成して表示するロジックの追加
このコンポーネントのC#コード部分は、次のようにします。
@code { private string prompt = ""; // プロンプト文 private string imageUrl = ""; // 生成画像のURL private bool isGenerating = false; // 生成中を示すフラグ private async Task GenerateImage() { // 入力がない場合は何もしない if (string.IsNullOrWhiteSpace(prompt)) return; isGenerating = true; try { // 後で追加 } finally { isGenerating = false; } } }
このページでは、テキストエリアでプロンプト(画像の説明)を入力し、ボタンクリックで画像生成を行います。ここでは一旦、画像生成の処理を空にしていますが、この後新規作成するサービスを利用する形にします。
画像生成ページのメニュー追加
次に、このページにアクセスできるようにナビゲーションメニューを更新します。LayoutフォルダのNavMenu.razorを開き、次のようにメニュー項目を追加します。
<div class="nav-scrollable" onclick="document.querySelector('.navbar-toggler').click()"> <nav class="flex-column"> ~中略~ <div class="nav-item px-3"> <NavLink class="nav-link" href="generate"> <span aria-hidden="true"></span> 画像生成 </NavLink> </div> </nav> </div>
画像生成を選択すれば、/generateとして定義されたページが表示されます。