我看到的所有示例都是在状态(更少/更满)小部件中初始化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的想法,或者如果我在objectBox
(位于HomePage
的上游)中初始化objectBox
,我如何从注入的JournalsRemoteDataSource
中访问objectBox
对象。
PS:在每次读/写事件时在JournalsRemoteDataSource
中重新打开盒子的性能非常差
=更新=,补充我对@vaind的评论
我已经在这个类似的question上找到了你的答案(不确定为什么我一开始没有看到它)。我希望这种方法也能在这里工作。但是,我仍然在初始化存储时遇到问题。我的原型来自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();
除了IntelliJ中的final Store _store
是灰色的(未使用的变量)之外,我还收到了这个错误
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'
发布于 2021-08-07 15:31:47
因此,遵循vaind的另一个答案,我实现了如下所示。我的架构遵循了Reso Coder的DDD和Clean architecture教程的合并。基本上,它是DDD,具有Clean Architecture的本地/远程数据源层。
基础设施目录
抽象数据源
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();
基础架构/核心中的可注入模块
@module
abstract class ObjectBoxInjectableModule {
@preResolve // <<<<<<<<<<<<< needed for async init
@lazySingleton
Future<Store> get store async => await openStore();
}
现在让它工作的诀窍是:我后来的错误是由于一个注入器init尚未完成而导致的。在将根文件夹中的injection.dart
更改为Future
并在main()
中await
调用后,它可以工作。injection.dart
现在看起来像这样:
final GetIt getIt = GetIt.instance;
@injectableInit
Future<void> configureInjection(String env) async {
$initGetIt(getIt, environment: env);
}
发布于 2021-08-06 16:34:33
我没有使用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
提供了一种重置的方法,这将导致重新打开相同的商店。为了避免在使用它时出现问题,还需要实现一个调用store.close()
的get_it
dispose
版本。
https://stackoverflow.com/questions/68679357
复制相似问题