Как получить доступ / вставить базу данных ObjectBox в репозиторий во Flutter
все примеры, которые я видел, инициализируют ObjectBox в виджете состояния (меньше / полностью). Я использую многоуровневую архитектуру (в настоящее время выполняю рефакторинг до DDD) и задаюсь вопросом, как правильно внедрить свой ObjectBox.
В свой репозиторий я ввожу источники данных с помощью пакетов injectable и getit с
@injectable
@LazySingleton (as: IJournalsRepository)
class JournalsRepository implements IJournalsRepository {
final JournalsRemoteDataSource journalsRemoteDataSource;
final JournalsLocalDataSource journalsLocalDataSource;
JournalsRepository(this.journalsLocalDataSource, this.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
в
MyApp()
(который предшествует
HomePage
)
PS: повторное открытие коробки в
JournalsRemoteDataSource
при каждом событии чтения / записи имеет очень низкую производительность
2 ответа
Итак, следуя другому напрасному ответу, я реализовал это следующим образом. Моя архитектура основана на слиянии руководств Reso Coder по DDD и чистой архитектуре. В основном это DDD с уровнем локального / удаленного источника данных чистой архитектуры.
ИНФРАСТРУКТУРА справочник
абстрактные источники данных
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();
}
А теперь уловка, чтобы заставить его работать: мои более поздние ошибки были вызваны еще не завершенной инициализацией инжектора. После изменения в корневой папке на
Future
и
await
звонок в
main()
, это сработало.
injection.dart
теперь выглядит так:
final GetIt getIt = GetIt.instance;
@injectableInit
Future<void> configureInjection(String env) async {
$initGetIt(getIt, environment: env);
}
У меня нет опыта работы с пакетами &, но из документации я думаю, что следующие альтернативы будут работать. Используя напрямую, не уверенный в правильном способе достижения того же с
injectable
(генератор для), но я думаю, если вы знакомы с ним, вы можете настроить его для генерации того же кода.
Альтернатива A, ленивый (асинхронный) синглтон
GetIt.I.registerSingletonAsync<Store>(openStore);
Альтернатива B, настройка в
main()
, вероятно, предпочтительнее
измени свой
main
чтобы что-то вроде:
void main() async {
GetIt.I.registerSingleton<Store>(await openStore());
runApp(MyApp());
}
Примечание. Похоже, предоставляет способ сброса настроек, который приведет к повторному открытию того же магазина. Чтобы избежать проблем, если вы его используете, вам также необходимо реализовать версию
get_it
с
dispose
это зовёт
store.close()
.