はじめに
Blazorを使っていると、「あれ?このデータを全体で共有したいんだけど…」と思うことがあるかもしれません。
そんな時に役立つのがAppStateパターンです。
このパターンを使えば、どのコンポーネントからでも共通のデータにアクセスできます。
今回は、その方法を学習したのでまとめます。
私は普段、C#でWindowsのデスクトップアプリを開発しています。
Webの技術を体系的に学び、しっかり活用した経験がなく用語の理解も怪しいので、超初歩的な内容になってます。
AppStateパターンの基本実装
アプリ全体で使いたいデータをプロパティ定義したクラスを作成し、それをサービスクラスとしてDIコンテナに登録します。それをデータを使いたい場所に注入すればどこからでもそのデータにアクセスできるというわけです。
例えば、以下のようにアプリ全体で使いたいプロパティを定義した、AppStateクラスを用意します。
public class AppState {
public string SharedData { get; set; }
}
定義したクラスをサービスとしてDIコンテナへ登録します。
// Program.cs
builder.Services.AddScoped<AppState>();
ここまでやれば、準備完了です。
次に、AppStateをコンポーネントから使用します。
以下のように@inject
をコンポーネントファイルの先頭に書くこと、DIに登録したクラスを使用できます。
// XXComponent.razor
@inject AppState appSate;
@code {
protected override void OnInitialized() {
appState.SharedData = "Updated Data";
}
}
スコープの違いと選び方
先ほどの例では、DI登録する際に、AddScoped
というメソッドを使いました。
BlazorのDIコンテナには、Scoped, Singleton, Transient という3つのスコープがあります。
それぞれの違いは以下です。
Scoped
現在のスコープ(通常はブラウザセッション)内で状態を保持するため、ページを切り替えても状態を保持します。
ログイン状態や一時的なユーザー設定など、ページのリロードや新しいタブを開くと消えても良いデータに使います。
例えば、ショッピングカート機能では、ユーザーがブラウザを閉じるか、リロードするまで選んだ商品は保持されるべきです。Scopedスコープを使えば、セッション中の情報を保持できます。
Singleton
アプリケーションのライフタイム全体でデータを共有したい場合に使用するもので、現在のスコープに限らずリロードしたりしても、状態を保持します。
アプリケーション全体で共通して使う設定データや、統計情報などです。
例えば、サイト全体で使用されるカスタムテーマ設定や、ユーザーの選択した言語設定などに使えると思います。
Transient
各リクエストごとに新しいインスタンスが生成されるため、状態は保持されず、ページ切り替えで状態が消えます。
主に一時的な操作に使います。
※AppStateパターンにおいて、内部変数のような扱いのTramsient
のスコープを使うことは無いかもしれませんが、スコープの1種ではあるため、列挙しました。
さいごに
前回の親から子コンポーネントのパラメータの受け渡し加えて、AppStateパターンも使えれば、Blazorにおけるパラメーターの取り扱いはばっちりじゃないでしょうか??
私が他を知らないだけかもしれませんが…
参考