LoginSignup
8

More than 1 year has passed since last update.

Flutterのget_itとRiverpodのProviderについて軽く紹介

Last updated at Posted at 2020-12-22

お仕事で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.instanceget<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.wathchref.readが使われます。

watchの場合は、値が変更されたときに Provider が再生成されますがreadの場合はされないです。

従来のProviderと比べてグローバル定数として変数宣言できます。
なので、従来のPrviderではツリー以外から参照しようとするとランタイム時にエラー(ProviderNotFoundException)が発生する場合がありますが、RiverPodのproviderでは起きないです。

個人的にはProviderNotFoundExceptionが発生しないのはかなり魅力的に思えます。

ただ、riverpodが現在v0.12.0で破壊的変更が今後あるかもしれないとのことの。

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
What you can do with signing up
8