0
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

get_itで依存性注入を行う

Last updated at Posted at 2024-06-29

はじめに

Flutterの開発で依存性注入(DI: Dependency Injection)を
シンプルに行うためのパッケージとして get_it があります。
この記事では、 get_it パッケージの基本的な使い方やメリットについて説明します。

依存性注入とは?
依存性注入とは、クラスが必要とする依存関係(他のクラスやサービス)を
外部から注入する設計パターンです。
これにより、コードの再利用性やテストのしやすさが向上します。

get_itとは?

get_it は、シンプルなサービスロケーターパッケージです。
主に以下のような機能を提供しており、依存関係管理を容易にします。

機能

  • サービスの登録と取得: 抽象クラスや実装クラスを登録し、
    アプリ全体で簡単にアクセス可能
  • 依存関係の注入: コンポーネントに必要なサービスを自動的に生成・提供
  • モックオブジェクトの利用: テストにおいて、実際のサービスを
    モックオブジェクトに置き換えて容易に検証可能
  • スコープ管理: 登録されたサービスの有効範囲を制御し、不要なメモリ使用を抑制

基本メソッド

メソッド名 説明
registerSingleton(T instance) シングルトンとしてインスタンスを登録する。アプリ全体で同一インスタンスが使用される。
registerFactory(T Function() factoryFunc) ファクトリーとして登録し、呼び出しごとに新しいインスタンスを生成する。
get() 登録された依存性を取得する。
isRegistered({Object instance}) 指定されたタイプの依存性が登録されているかどうかを確認する。
unregister({Object instance, bool disposing}) 指定されたタイプの依存性を登録解除する。disposingがtrueの場合、登録解除時にインスタンスの破棄を行う。
reset() すべての登録された依存性を解除する。
resetLazySingleton( {Object instance}) 指定されたタイプの遅延シングルトンをリセットする。次回アクセス時に再作成される。
allowReassignment 同じタイプの依存性を再登録できるようにするフラグを設定する。
registerLazySingleton(T Function() factoryFunc) 初回アクセス時にインスタンスを生成する遅延シングルトンを登録する。
getAsync() 非同期に依存性を取得する。

get_it パッケージの導入

pubspec.yamlget_it を追加します。

dependencies:
  flutter:
    sdk: flutter
  get_it: ^7.2.0  # 最新バージョンを確認してください

基本的な使い方

get_it を使うためには、まず、シングルトンインスタンスを取得し、
必要なクラスやサービスを登録する必要があります。

1. シングルトンのインスタンス取得

まず、 GetIt のシングルトンインスタンスを取得します。

import 'package:get_it/get_it.dart';

final getIt = GetIt.instance;

2. クラス(依存性)の登録

次に、依存性を登録します。
必要なクラスやサービスを登録します。
※ここでは、 MyService というサービスクラスを登録しています。

class MyService {
  void doSomething() {
    print('Doing something...');
  }
}

void setupLocator() {
  getIt.registerSingleton<MyService>(MyService());
}
// setupLocator 関数はアプリのエントリーポイントで一度呼び出します。
void main() {
  setupLocator();
  runApp(MyApp());
}

3. クラス(依存性)の取得

登録したクラスやサービスを取得して使用します。

import 'package:flutter/material.dart';

class MyHomePage extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    final myService = getIt<MyService>();

    return Scaffold(
      appBar: AppBar(
        title: Text('GetIt Example'),
      ),
      body: Center(
        child: ElevatedButton(
          onPressed: () {
            myService.doSomething();
          },
          child: Text('Do Something'),
        ),
      ),
    );
  }
}

get_it のメリット

  • グローバルアクセス: どこからでも依存関係にアクセスできるため、コードの管理が容易になります。
  • テストのしやすさ: 依存関係を簡単にモックに置き換えることができるため、テストが容易になります。
  • ライフサイクル管理: シングルトンやファクトリーのライフサイクルを明確に管理することができます。
  • 可読性と保守性の向上: 依存性の管理がシンプルになることで、コードの可読性と保守性が向上する。

get_itを使用した実践例

より具体的なユーザー認証アプリの例を通じて、get_itの使用方法を説明します。

ステップ1:依存性の登録

まず、setupLocator関数で必要な依存性を登録します

import 'package:get_it/get_it.dart';

final getIt = GetIt.instance;

void setupLocator() {
  getIt.registerSingleton<ApiService>(ApiService());
  getIt.registerSingleton<AuthService>(AuthService(getIt<ApiService>()));
  getIt.registerSingleton<UserRepository>(UserRepository(getIt<AuthService>()));
}

void main() {
  setupLocator();
  runApp(MyApp());
}

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: MyApp(),
    );
  }
}

ステップ2:サービスクラスの実装

次に、ApiServiceとAuthServiceのサービスクラスを実装します

class ApiService {
  String fetchData() {
    return 'Fetched Data';
  }
}

class AuthService {
  final ApiService apiService;

  AuthService(this.apiService);

  void login() {
    // ログイン処理
    apiService.fetchData();
    print('User logged in');
  }
}

ステップ3:リポジトリクラスの実装

リポジトリクラスを実装して、サービスクラスを利用します。

class UserRepository {
  final AuthService authService;

  UserRepository(this.authService);

  void authenticateUser() {
    authService.login();
    print('User authenticated');
  }
}

ステップ4:UIの実装

最後に、UIを実装します

class MyApp extends StatelessWidget {
  final _userRepository = getIt<UserRepository>();

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('Home Page'),
      ),
      body: Center(
        child: ElevatedButton(
          onPressed: () {
            _userRepository.authenticateUser();
          },
          child: Text('Authenticate User'),
        ),
      ),
    );
  }
}

5. テストでのget_itの活用

get_itを使用すると、依存性の注入を簡単にモックに置き換えることができます。

void main() {
  setUpAll(() {
    getIt.registerSingleton<ApiService>(MockApiService());
    getIt.registerSingleton<AuthService>(MockAuthService(getIt<ApiService>()));
    getIt.registerSingleton<UserRepository>(UserRepository(getIt<AuthService>()));
  });

  tearDown(() {
    getIt.reset();
  });

  test('authenticateUser test', () {
    final userRepository = getIt<UserRepository>();
    userRepository.authenticateUser;
  });
}
  • 依存性の登録: setupLocator 関数内で依存性を登録します。
    ApiService , AuthService , UserRepository の各クラスを get_it に登録します。

  • サービスクラスの実装: ApiServiceAuthService を実装し、
    AuthService では ApiService を利用します。

  • リポジトリクラスの実装: UserRepository を実装し、
    AuthService を利用してユーザー認証を行います。

  • UIの実装: UI でリポジトリを利用し、ボタンが押されたときに
    ユーザー認証を実行します。

  • テストでのget_itの活用: テスト環境で get_it を使用し、
    モックサービスを登録して依存性注入を行い、テストケースを実行します。

まとめ

get_it パッケージを使用することで、依存性管理が大幅に簡潔になります。
これにより、コードの保守性が向上し、テストの作成も容易になるため、
アプリケーションの設計がより柔軟で保守しやす形になります。
これを機にぜひ活用してみてください。

告知

最後にお知らせとなりますが、イーディーエーでは一緒に働くエンジニアを
募集しております。詳しくは採用情報ページをご確認ください。

みなさまからのご応募をお待ちしております。

0
2
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
  3. You can use dark theme
What you can do with signing up
0
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?