🔧 そもそもDI(依存性注入)とは?
DI(Dependency Injection)とは、「あるクラスが必要とする他のオブジェクト(依存物)を、自分で作るのではなく外部から提供してもらう設計手法」です。
❌ 従来の書き方(密結合)
public class UserService {
private final UserRepository repository = new UserRepository(); // ← 自分で依存を生成してしまっている
}
✅ DIを使った書き方(疎結合)
public class UserService {
private final UserRepository repository;
public UserService(UserRepository repository) {
this.repository = repository; // ← 外部から注入してもらう
}
}
このようにすると、テストしやすくなり、依存関係の変更にも強くなります。
🧱 AndroidでDIが重要な理由
JavaではSpringのようなDIコンテナを使うことでDIが当たり前になりますが、Androidでは明示的にDIの設計を意識しないと、すぐに密結合なコードになります。
また、Androidアプリではライフサイクルが複雑なため、スコープ(Activity単位・アプリ全体など)を意識した依存性管理が必要になります。
🧰 AndroidでのDIの手段
1. 手動DI(基本形)
最初はコンストラクタやセッターで手動で依存性を渡す形でも十分学べます。
public class MainViewModel {
private final TaskRepository repository;
public MainViewModel(TaskRepository repository) {
this.repository = repository;
}
}
Activity
から ViewModel を生成する際に渡す:
TaskRepository repository = new TaskRepository();
MainViewModel vm = new MainViewModel(repository);
2. Dagger2 / Hilt を使った自動DI
Dagger2 は Google 公式の DI ライブラリで、Hilt はその上に構築された簡易化された DI フレームワークです。
Hilt の構成例
@HiltAndroidApp
public class MyApp extends Application { }
@AndroidEntryPoint
public class MainActivity extends AppCompatActivity {
@Inject
TaskRepository repository; // ← Hiltが注入してくれる
}
依存関係を提供するクラス:
@Module
@InstallIn(SingletonComponent.class)
public class RepositoryModule {
@Provides
public static TaskRepository provideRepository() {
return new TaskRepository();
}
}
💡 Hiltは、Springでいうところの
@Autowired
や@ComponentScan
のような自動注入を、Android向けに最適化した仕組みだと考えるとわかりやすいです。
🎯 Javaエンジニア向け補足
Java(Springなど) | Android(Hilt/Daggerなど) |
---|---|
@Autowired | @Inject |
@Component | @Module + @Provides |
コンテナ:Spring | コンテナ:Hilt/Dagger |
- スコープの制御(
@Singleton
など)もHiltで可能です。 - AndroidではActivityスコープ、ViewModelスコープ、Applicationスコープなどが重要になります。
✅ まとめ
- DIとは「依存性を外から渡す」設計手法。
- Androidでは疎結合な設計を実現し、テスト可能性・拡張性を高めるために重要。
- まずは手動DIで理解を深め、その後 Hilt による自動DIに移行していくとスムーズ。