Как получить доступ / вставить базу данных 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().

Другие вопросы по тегам