Part 1: https://dev.tora-tech.com/dependency-injection-trong-flutter-part-1/
Giải quyết dependency
Có những trường hợp object A cần cung cấp object B mới có thể hoạt động (A depends on B), vậy thì chúng ta sẽ phải làm như nào?
Factory/singleton A phụ thuộc vào factory/singleton B
class A {
final B b;
const A(this.b);
}
class B {
}
// Đăng kí B trước tiên
getIt.registerSingleton<B>(B());
getIt.registerFactory<A>(() {
// Lấy object B bên trên
final b = getIt.get<B>();
// Truyền vào constructor của A
return A(b);
});
Factory/singleton A phụ thuộc vào asynchronous factory/singleton B
Lúc này phải chuyển hàm khởi tạo A thành asynchronous chứ không còn dùng được synchronous nữa, cụ thể là phải dùng:
registerFactoryAsync
thay vìregisterFactory
registerSingletonAsync
thay vìregisterSingleton
class A {
final B b;
const A(this.b);
}
class B {
static Future<B> createAsync() {
// Khởi tạo B
}
}
// Đăng kí B trước tiên
getIt.registerSingletonAsync<B>(() => B.createAsync());
getIt.registerFactoryAsync<A>(() async {
// Chờ và lấy object B bên trên...
final b = await getIt.getAsync<B>();
// Truyền vào constructor của A
return A(b);
});
Asynchronous factory/singleton A phụ thuộc vào factory/singleton B
Phần này cũng khá giống với Factory/singleton A phụ thuộc vào factory/singleton B
class A {
final B b;
const A(this.b);
static Future<A> createAsync(B b) {
// ... khởi tạo A
}
}
class B {
}
// đăng kí B trước tiên
getIt.registerSingleton<B>(B())
getIt.registerFactoryAsync<A>(() async {
// lấy object B bên trên...
final b = getIt.get<B>();
// ...truyền vào hàm khởi tạo của A
return await A.createAsync(b);
});
Asynchronous factory/singleton A phụ thuộc vào asynchronous factory/singleton B
Phần này cũng khá giống với Factory/singleton A phụ thuộc vào asynchronous factory/singleton B
class A {
final B b;
const A(this.b);
static Future<A> createAsync(B b) {
// ... khởi tạo A
}
}
class B {
static Future<B> createAsync() {
// ... khởi tạo B
}
}
// đăng kí B trước tiên
getIt.registerSingletonAsync<B>(() => B.createAsync())
getIt.registerFactoryAsync<A>(() async {
// lấy object B bên trên...
final b = await getIt.getAsync<B>();
// ...truyền vào hàm khởi tạo của A
return await A.createAsync(b);
});
Tự động đăng kí dependency với Injectable
Cơ chế inject dependency chỉ cần thêm annotation trên đầu class cần inject và nó sẽ tự động tìm và inject luôn cho mình chứ không phải declare ra như bên trên.
Ta cần 2 plugin là build_runner và injectable để thực hiện điều này
Cài đặt
Đầu tiên chúng ta cần thêm vào pubspec.yaml
, chạy flutter packages get
để cài đặt.
https://pub.dev/packages/build_runner
https://pub.dev/packages/injectable
https://pub.dev/packages/injectable_generator
dependencies:
...
injectable: ^1.0.4
dev_dependencies:
...
injectable_generator: ^1.0.4
build_runner: ^1.10.2
Sửa file injection_container.dart thành như sau:
import 'package:get_it/get_it.dart';
import 'package:injectable/injectable.dart';
import 'injection_container.config.dart';
final sl = GetIt.instance;
@InjectableInit()
void configureDependencies() => sl.init();
Chạy lệnh sau để fix các lỗi xuất hiện
flutter packages pub run build_runner build
Giờ quay lại với các phụ thuộc và thêm vào @injectable
@injectable
class NumBloc {
//...
}
Tất nhiên ngoài factory ra, chúng ta cũng có thể dùng singleton và lazy-singleton bằng các annotation @singleton
và @lazySingleton
.
Với asynchronous factory bạn có thể dùng @injectable
trên class và @factoryMethod
trên hàm khởi tạo như sau:
import 'package:injectable/injectable.dart';
@injectable
class A {
@factoryMethod
static Future<A> createAsync() {
//...
}
}