お仕事で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で破壊的変更が今後あるかもしれないとのことの。