如何在 Flutter 中 access/inject 存储库中的 ObjectBox 数据库 - Reso Coder DDD
How to access/inject ObjectBox database in repository in Flutter - Reso Coder DDD
我看到的所有示例都是在 State(less/full)Widget 中初始化 ObjectBox。我正在使用分层架构(目前正在重构为 DDD)并且想知道如何正确地注入我的 ObjectBox。
在我的存储库中,我使用 injectable 和 getit 包注入数据源
@injectable
@LazySingleton (as: IJournalsRepository)
class JournalsRepository implements IJournalsRepository {
final JournalsRemoteDataSource journalsRemoteDataSource;
final JournalsLocalDataSource journalsLocalDataSource;
JournalsRepository(this.journalsLocalDataSource, this.journalsRemoteDataSource);
这些包然后创建 JournalsRemoteDataSource
和 JournalsRemoteDataSource
的实例并将其注入存储库。
ObjectBox 示例显示初始化
class _MyHomePageState extends State<MyHomePage> {
Store? _store;
@override
void initState() {
super.initState();
openStore().then((Store store) => _store = store;);
}
@override
void dispose() {
_store?.close(); // don't forget to close the store
super.dispose();
}
}
所以我不知道注入器如何初始化 ObjectBox,或者如果我在 MyApp()
(HomePage
的上游)
PS:在每个 read/write 事件中重新打开 JournalsRemoteDataSource
中的框性能非常差
==========更新==========
补充我对@vaind
的评论
我同时在这个类似的 上找到了你的答案(不知道为什么我一开始没有看到它)。我希望这种方法也能在这里发挥作用。但是,我在初始化商店时仍然遇到问题。我的原型来自 Firestore,看起来像这样:
import 'package:firebase_auth/firebase_auth.dart';
import 'package:injectable/injectable.dart';
@module
abstract class FirebaseInjectableModule {
@lazySingleton
FirebaseAuth get firebaseAuth => FirebaseAuth.instance;
}
虽然我不明白 getter firebaseAuth
是从哪里来的,也没有找到任何解释。无论如何,我将其改编为
import 'package:injectable/injectable.dart';
import 'package:objectbox/objectbox.dart';
import 'package:test/objectbox.g.dart';
@module
abstract class ObjectboxInjectableModule {
@lazySingleton
Future<Store> get store async => await openStore();
}
并将其与
一起使用
@LazySingleton (as: ILocalDataSource)
class ObjectBoxDataSource implements ILocalDataSource {
final Store _store;
final Box<JournalOboxEntity> _box;
ObjectBoxDataSource(this._store) : _box = _store.box();
除了 final Store _store
在 IntelliJ 中是灰色的(未使用的变量),我收到错误
You tried to access an instance of Store that is not ready yet
'package:get_it/get_it_impl.dart':
Failed assertion: line 404 pos 9: 'instanceFactory.isReady'
我没有使用软件包 get_it
和 injectable
的经验,但根据文档,我认为以下替代方法可行。直接使用 get_it
,不确定使用 injectable
(get_it
的生成器)实现相同的正确方法,但我想如果您熟悉它,您可以配置它来生成相同的代码。
备选方案 A,惰性(异步)单例
GetIt.I.registerSingletonAsync<Store>(openStore);
备选方案 B,在 main()
中设置,可能更可取
将您的 main
更改为:
void main() async {
GetIt.I.registerSingleton<Store>(await openStore());
runApp(MyApp());
}
注意:看起来 get_it
提供了一种重置方法,这将导致重新打开同一家商店。为避免使用它时出现问题,您还需要实施 get_it
的 dispose
版本,该版本调用 store.close()
.
所以在vaind的另一个回答之后,我实现了如下。我的架构遵循 Reso Coder 的 DDD 和 Clean Architecture 教程的合并。基本上它是 DDD 与 Clean Architecture 的 local/remote 数据源层。
INFRASTRUCTURE 目录
抽象数据源
abstract class ILocalDataSource {
Future<JournalDto> getJournal(int id);
Future<void> storeJournal(JournalDto record);
}
abstract class IRemoteDataSource {
Future<JournalDto> getJournal(int problemClassId);
}
数据源实现
@LazySingleton (as: ILocalDataSource)
class ObjectBoxDataSource implements ILocalDataSource {
final Store _store;
final Box<JournalOboxEntity> _box;
ObjectBoxDataSource(this._store) : _box = _store.box();
infrastructure/core
中的可注入模块
@module
abstract class ObjectBoxInjectableModule {
@preResolve // <<<<<<<<<<<<< needed for async init
@lazySingleton
Future<Store> get store async => await openStore();
}
现在是让它工作的诀窍:我后来的错误是由尚未完成的注入器初始化引起的。将根文件夹中的 injection.dart
更改为 Future
并 await
在 main()
中调用后,它起作用了。 injection.dart
现在看起来像这样:
final GetIt getIt = GetIt.instance;
@injectableInit
Future<void> configureInjection(String env) async {
$initGetIt(getIt, environment: env);
}
我看到的所有示例都是在 State(less/full)Widget 中初始化 ObjectBox。我正在使用分层架构(目前正在重构为 DDD)并且想知道如何正确地注入我的 ObjectBox。
在我的存储库中,我使用 injectable 和 getit 包注入数据源
@injectable
@LazySingleton (as: IJournalsRepository)
class JournalsRepository implements IJournalsRepository {
final JournalsRemoteDataSource journalsRemoteDataSource;
final JournalsLocalDataSource journalsLocalDataSource;
JournalsRepository(this.journalsLocalDataSource, this.journalsRemoteDataSource);
这些包然后创建 JournalsRemoteDataSource
和 JournalsRemoteDataSource
的实例并将其注入存储库。
ObjectBox 示例显示初始化
class _MyHomePageState extends State<MyHomePage> {
Store? _store;
@override
void initState() {
super.initState();
openStore().then((Store store) => _store = store;);
}
@override
void dispose() {
_store?.close(); // don't forget to close the store
super.dispose();
}
}
所以我不知道注入器如何初始化 ObjectBox,或者如果我在 MyApp()
(HomePage
的上游)
PS:在每个 read/write 事件中重新打开 JournalsRemoteDataSource
中的框性能非常差
==========更新========== 补充我对@vaind
的评论我同时在这个类似的
import 'package:firebase_auth/firebase_auth.dart';
import 'package:injectable/injectable.dart';
@module
abstract class FirebaseInjectableModule {
@lazySingleton
FirebaseAuth get firebaseAuth => FirebaseAuth.instance;
}
虽然我不明白 getter firebaseAuth
是从哪里来的,也没有找到任何解释。无论如何,我将其改编为
import 'package:injectable/injectable.dart';
import 'package:objectbox/objectbox.dart';
import 'package:test/objectbox.g.dart';
@module
abstract class ObjectboxInjectableModule {
@lazySingleton
Future<Store> get store async => await openStore();
}
并将其与
一起使用@LazySingleton (as: ILocalDataSource)
class ObjectBoxDataSource implements ILocalDataSource {
final Store _store;
final Box<JournalOboxEntity> _box;
ObjectBoxDataSource(this._store) : _box = _store.box();
除了 final Store _store
在 IntelliJ 中是灰色的(未使用的变量),我收到错误
You tried to access an instance of Store that is not ready yet
'package:get_it/get_it_impl.dart':
Failed assertion: line 404 pos 9: 'instanceFactory.isReady'
我没有使用软件包 get_it
和 injectable
的经验,但根据文档,我认为以下替代方法可行。直接使用 get_it
,不确定使用 injectable
(get_it
的生成器)实现相同的正确方法,但我想如果您熟悉它,您可以配置它来生成相同的代码。
备选方案 A,惰性(异步)单例
GetIt.I.registerSingletonAsync<Store>(openStore);
备选方案 B,在 main()
中设置,可能更可取
将您的 main
更改为:
void main() async {
GetIt.I.registerSingleton<Store>(await openStore());
runApp(MyApp());
}
注意:看起来 get_it
提供了一种重置方法,这将导致重新打开同一家商店。为避免使用它时出现问题,您还需要实施 get_it
的 dispose
版本,该版本调用 store.close()
.
所以在vaind的另一个回答之后,我实现了如下。我的架构遵循 Reso Coder 的 DDD 和 Clean Architecture 教程的合并。基本上它是 DDD 与 Clean Architecture 的 local/remote 数据源层。
INFRASTRUCTURE 目录
抽象数据源
abstract class ILocalDataSource {
Future<JournalDto> getJournal(int id);
Future<void> storeJournal(JournalDto record);
}
abstract class IRemoteDataSource {
Future<JournalDto> getJournal(int problemClassId);
}
数据源实现
@LazySingleton (as: ILocalDataSource)
class ObjectBoxDataSource implements ILocalDataSource {
final Store _store;
final Box<JournalOboxEntity> _box;
ObjectBoxDataSource(this._store) : _box = _store.box();
infrastructure/core
中的可注入模块@module
abstract class ObjectBoxInjectableModule {
@preResolve // <<<<<<<<<<<<< needed for async init
@lazySingleton
Future<Store> get store async => await openStore();
}
现在是让它工作的诀窍:我后来的错误是由尚未完成的注入器初始化引起的。将根文件夹中的 injection.dart
更改为 Future
并 await
在 main()
中调用后,它起作用了。 injection.dart
现在看起来像这样:
final GetIt getIt = GetIt.instance;
@injectableInit
Future<void> configureInjection(String env) async {
$initGetIt(getIt, environment: env);
}