はじめに
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.yaml
に get_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
に登録します。 -
サービスクラスの実装:
ApiService
とAuthService
を実装し、
AuthService
ではApiService
を利用します。 -
リポジトリクラスの実装:
UserRepository
を実装し、
AuthService
を利用してユーザー認証を行います。 -
UIの実装: UI でリポジトリを利用し、ボタンが押されたときに
ユーザー認証を実行します。 -
テストでのget_itの活用: テスト環境で
get_it
を使用し、
モックサービスを登録して依存性注入を行い、テストケースを実行します。
まとめ
get_it
パッケージを使用することで、依存性管理が大幅に簡潔になります。
これにより、コードの保守性が向上し、テストの作成も容易になるため、
アプリケーションの設計がより柔軟で保守しやす形になります。
これを機にぜひ活用してみてください。
告知
最後にお知らせとなりますが、イーディーエーでは一緒に働くエンジニアを
募集しております。詳しくは採用情報ページをご確認ください。
みなさまからのご応募をお待ちしております。