[Flutter]get_itパッケージについて語る

get_itパッケージとは

get_it パッケージは、依存性の管理に使用されるパッケージで、依存関係を登録し、アプリケーション内で再利用するためのクラスのインスタンスを提供します。

もう少し噛み砕いて説明

考え方としては、get_it は「箱」のようなものです。この「箱」に、アプリケーションが使うさまざまな部品(クラスのインスタンスなど)を入れておきます。そうすることで、アプリケーションのどこからでも、この箱を開けて必要な部品を取り出して使うことができるようになります。

get_itの具体的な役割は3つ

  1. 依存性の管理: get_it はアプリケーションのさまざまな部分(依存関係)がどのように組み合わさって動作するかを管理するために使います。例えば、データベースへのアクセスを行うクラスや、ネットワーク通信を行うクラスなどがこれに当たります。

  2. 依存関係の登録: アプリケーションを起動するときに、これらの依存関係(部品)を get_it に「登録」します。つまり、「このアプリでは、この部品を使いますよ」と宣言するようなイメージです。

  3. 再利用のための提供: いったん依存関係を登録すると、アプリケーションのどの部分からでも、get_it を通じて簡単にその部品を取り出して使うことができます。これにより、同じ部品を何度も作る必要がなく、効率的にアプリケーションを動かすことができます。

要するに、get_it はアプリケーション内で必要な部品を一箇所にまとめ、必要な時にすぐに取り出せるようにするための便利なツールです。これにより、アプリケーションのコードがすっきりと整理され、部品の使い回しがしやすくなります。

そもそも依存関係について知りたい方はこちらへ

要するに。

アプリのコードが整理され、依存部品の再利用が容易になり、テストやメンテナンスが簡単になります。

Get_itを使ってみよう

get_itパッケージを取得

まずは、get_itパッケージを取得してきます。

今回は、画面遷移に関わるナビゲーションキーを例に挙げて説明します。GetIt を使用してナビゲーションキーを管理することにより、アプリケーション全体でナビゲーションの状態を一元管理でき、どこからでも同じ方法で画面遷移を制御することが可能になります。これにより、ナビゲーションの複雑さが減少し、コードの整理や保守性が向上します。

locator.dartファイルを作成する

「locator.dart」ファイルを作り、下記のようにコードを記載します。

lib/locator.dart

import 'package:get_it/get_it.dart';
import 'navigator/navigator.dart';

GetIt locator = GetIt.instance;

Future<void> setupLocator() async {
  await locator.reset();
  locator.registerLazySingleton<NavigationController>(NavigationController.new);
}

上記のコードを説明する

GetIt.instance
GetIt のシングルトンインスタンスにアクセスするためのスタティックメソッドです。これにより、アプリケーション全体で一貫したアクセスポイントが提供されます。

await locator.reset();
reset メソッドは GetIt インスタンスをリセットします。これは、すべての登録された依存性をクリアし、ロケータを初期状態に戻します。

locator.registerLazySingleton<NavigationController>(NavigationController.new);
・registerLazySingleton
メソッドは、指定された型のシングルトンインスタンスを登録します。ここでは、NavigationController のシングルトンを登録しています。
・NavigationController.new は、NavigationController の新しいインスタンスを生成するためのファクトリ関数を指しています。

設定したNavigationControllerを呼び出す

アプリケーション全体でのナビゲーション管理する場合、グローバル(トップレベル)に設定します。
呼び出し方はこんな感じ。

final navigatorKey = locator.get<NavigationController>().navigatorKey;

GetIt のロケータを使用して NavigationController インスタンスにアクセスし、その navigatorKey プロパティを取得します。
このように記述することで、アプリケーション全体でナビゲーション状態の一貫性を保つことができます。これは、複数の場所でナビゲーショを使用する場合、大切になってきます。

下記は例です。

class App extends HookConsumerWidget {
  const App({super.key});

  @override
  Widget build(BuildContext context, WidgetRef ref) {

    final navigatorKey = locator.get<NavigationController>().navigatorKey;

    return MaterialApp(

      navigatorKey: navigatorKey,
      ...

    );
  }
}

こうすることで、この navigatorKey は、アプリケーションのナビゲータ(画面遷移を管理する部分)に渡され、アプリ内のどこからでも一貫した画面遷移を行うことができるようにします。

サンプルコード

最後に、サンプルコードを記載しますので、ぜひ皆さんも試してみてください!

lib/locator.dart

import 'package:get_it/get_it.dart';

import 'navigator/navigator.dart';

GetIt locator = GetIt.instance;

Future<void> setupLocator() async {
  await locator.reset();
  locator.registerLazySingleton<NavigationController>(NavigationController.new);
}

lib/ui/app.dart

import 'package:flutter/material.dart';
import 'package:hooks_riverpod/hooks_riverpod.dart';

import 'package:testApp/ui/test/first_page.dart';
import 'package:testApp/ui/test/second_page.dart';

import 'package:testApp/locator.dart';
import '../navigator/navigator.dart';

class App extends HookConsumerWidget {
  const App({super.key});

  @override
  Widget build(BuildContext context, WidgetRef ref) {

    final navigatorKey = locator.get<NavigationController>().navigatorKey;
    print(navigatorKey);

    return MaterialApp(
      navigatorKey: navigatorKey,
      initialRoute: '/first',
      onGenerateRoute: (RouteSettings settings) {
        switch (settings.name) {
          case '/first':
            return MaterialPageRoute(builder: (_) => const FirstPage());
          case '/second':
            return MaterialPageRoute(builder: (_) => const SecondPage());
        }
        return null;
      }
    );
  }
}

lib/ui/test/first_page.dart

import 'package:flutter/material.dart';

import 'package:testApp/ui/test/second_page.dart';

import '../../locator.dart';
import '../../navigator/navigator.dart';

class FirstPage extends StatefulWidget {
  const FirstPage({super.key});

  static String routeName = '/';

  @override
  State<FirstPage> createState() => _FirstPageState();
}

class _FirstPageState extends State<FirstPage> {
  final navigatorKey = locator.get<NavigationController>().navigatorKey;

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      backgroundColor: Colors.red,
      body: Center(
        child: FloatingActionButton(
          child: const Text('1'),
          onPressed: () {
            Navigator.of(context).pushNamed(
                SecondPage.routeName,
            );
          },
        ),
      ),
    );
  }
}

以上です。最後まで見ていただき、ありがとうございました。

この記事が気に入ったらサポートをしてみませんか?