お仕事でFlutterを触っており、
FlutterのDIではget_itパッケージが使用しています。
最近になってriverpodのProviderを使用して書く場面があって、それぞれの書き方を紹介します。
get_it
パッケージの場合
簡易なget_it
パッケージで書いた例です。
まず、main.dartに該当するmain()
で初期化しています。
例えばネットワーク通信などを実装しているクラスをApiClient
として、..registerLazySingleton<ApiClient>(() => ApiClient())
のGet.instance
に登録します。
GetIt getIt = GetIt.instance;
void main() {
setupGetIt();
runApp(App()):
}
void setupGetIt() {
getIt
..registerLazySingleton<ApiClient>(() => ApiClient()) //ここ
}
class ApiClient {
void method() {
}
}
次にApiClient.method()
が呼ばれる側です。
GetIt.instance
のget<T>
でインスタンスを呼び出します。
class App {
void method() {
getIt.get<App>().method();
}
}
riverPodのproviderを使った場合
まずProviderを使用する場合、ProviderScope
を設定します。
void main() {
runApp(ProviderScope(child: MyApp()));
}
次にProviderの宣言文は以下の通りです。
final sampleProvider = Provider<T>((_) => T);
下記では、FirebaseAuthを使った例で書いています。
/// Firebase Auth インスタンスの作成
final firebaseAuthProvider =
Provider<FirebaseAuth>((_) => FirebaseAuth.instance);
/// firebaseAuthProviderを使ってProvider宣言
final authDataSourceProvider = Provider<AuthDataSource>(
(ref) => AuthDataSourceImpl(ref.read(firebaseAuthProvider)));
abstract class AuthDataSource {
Future<User> signIn();
Future<void> signOut();
}
class AuthDataSourceImpl implements AuthDataSource {
AuthDataSourceImpl(this._firebaseAuth);
final firebase.FirebaseAuth _firebaseAuth;
@override
Future<firebase.User> signIn() async {
// 省略
}
@override
Future<void> signOut() {
// 省略
}
}
AuthDataSourceImpl
にあるsignIn()
やsingOut()
に内部実装は割愛しましたが、
実際にはクレデンシャル(idToken,リフレッシュトークン)の設定やFirebaseAuth.signInWithCredential()
などのログイン・ログアウトに関する詳細な実装が記述します。
上の例では、Providerから他のProviderにアクセスしています。
final authDataSourceProvider = Provider<AuthDataSource>((ref) => AuthDataSourceImpl(ref.read(firebaseAuthProvider)));
他のProviderにアクセスするにはref.wathch
とref.read
が使われます。
watch
の場合は、値が変更されたときに Provider が再生成されますがread
の場合はされないです。
従来のProviderと比べてグローバル定数として変数宣言できます。
なので、従来のPrviderではツリー以外から参照しようとするとランタイム時にエラー(ProviderNotFoundException
)が発生する場合がありますが、RiverPodのproviderでは起きないです。
個人的にはProviderNotFoundException
が発生しないのはかなり魅力的に思えます。
ただ、riverpodが現在v0.12.0で破壊的変更が今後あるかもしれないとのことの。