👏
riverpod_generatorで依存性注入(DI)
はじめに
riverpod_generatorを導入すると、各providerの書き方が大きく変わってしまうので、その場合で依存性注入(DI)を構築する方法を紹介したいと思います。
記事の対象者
-
依存性注入(DI)に馴染みのある方
-
riverpodで依存性注入を構築したい方
-
riverpod_generatorを利用したい方
riverpodにおけるDI
その前に、まずはriverpod
のみで依存性注入をやってみましょう。
実装例
final engineAProvider = Provider<Engine>((_) => EngineA());
final engineBProvider = Provider<Engine>((_) => EngineB());
abstract class Engine {
void start() {}
}
class EngineA implements Engine {
void start() {
debugPrint('Engine A started.');
}
}
class EngineB implements Engine {
void start() {
debugPrint('Engine B started.');
}
}
final carAProvider = Provider((ref) => Car(engine: ref.watch(engineAProvider)));
final carBProvider = Provider((ref) => Car(engine: ref.watch(engineBProvider)));
class Car {
const Car({required this.engine});
final Engine engine;
void drive() {
engine.start();
}
}
実行結果
// Print: Engine A started.
ref.read(carAProvider).drive();
// Print: Engine B started.
ref.read(carBProvider).drive();
上記の通り、ProviderでEngine
のインスタンスを提供してCar
に渡しています。
Engine
を生成するProviderを変えることで、異なるEngine
を持つCar
を作ることが可能になります。
このようにDIを行うことで、テストが容易になり、変化に強いアプリを作りやすくなります。
riverpod_generatorを利用したDI
さーて、riverpod_generator
の場合はどうすれば良いのでしょうか?
実装例
abstract class Engine {
void start() {}
}
(keepAlive: true)
class EngineA extends _$EngineA implements Engine {
Engine build() => this;
void start() {
debugPrint('Engine A started');
}
}
(keepAlive: true)
class EngineB extends _$EngineB implements Engine {
Engine build() => this;
void start() {
debugPrint('Engine B started');
}
}
(keepAlive: true)
Car carA(CarARef ref) => Car(engine: ref.watch(engineAProvider));
(keepAlive: true)
Car carB(CarBRef ref) => Car(engine: ref.watch(engineBProvider));
class Car {
const Car({required this.engine});
final Engine engine;
void drive() {
engine.start();
}
}
実行結果
// Print: Engine A started.
ref.read(carAProvider).drive();
// Print: Engine B started.
ref.read(carBProvider).drive();
EngineA
、EngineB
それぞれをProviderClassに変更し、CarA
とCarB
を生成するProviderを再作成します。
それで、マイグレーションする前と全く同じ仕組みを作ることができました。
さいごに
この記事では、riverpod_generator
を利用した依存性注入(DI)を構築する方法を紹介しました。
現時点でriverpod_generator
はoptionの扱いになるのですが、作者のRemiさんは
riverpod_generator
は未来に向けた仕組みで、少し不便なところもあるのですが使うのをおすすめします。
と述べているため、未来に備えてどんどん使っていきましょう。
Discussion