How to access/inject ObjectBox database in repository in Flutter - Reso Coder DDD
So following another answer of vaind, I implemented this as follows. My architecture follows a merge of Reso Coder's DDD and Clean Architecture tutorials. Basically it is DDD with the local/remote data source layer of Clean Architecture.
INFRASTRUCTURE directory
abstract data sources
abstract class ILocalDataSource {
Future<JournalDto> getJournal(int id);
Future<void> storeJournal(JournalDto record);
}
abstract class IRemoteDataSource {
Future<JournalDto> getJournal(int problemClassId);
}
data source implementation
@LazySingleton (as: ILocalDataSource)
class ObjectBoxDataSource implements ILocalDataSource {
final Store _store;
final Box<JournalOboxEntity> _box;
ObjectBoxDataSource(this._store) : _box = _store.box();
injectable module in infrastructure/core
@module
abstract class ObjectBoxInjectableModule {
@preResolve // <<<<<<<<<<<<< needed for async init
@lazySingleton
Future<Store> get store async => await openStore();
}
And now the trick to get it work: My later errors where caused by an injector init not yet finished. After changing injection.dart
in the root folder to a Future
and await
ing the call in main()
, it worked. injection.dart
now looks like this:
final GetIt getIt = GetIt.instance;
@injectableInit
Future<void> configureInjection(String env) async {
$initGetIt(getIt, environment: env);
}
w461
Programmed C long time ago, did some minor VBA in between and currently I am trying to create some basic home schooling apps in flutter and/or swift - just in case...
Updated on November 23, 2022Comments
-
w461 over 1 year
all the examples, I have seen, initialize ObjectBox in a State(less/full)Widget. I am using a layered architecture (currently refactoring to DDD) and wonder, how to inject my ObjectBox properly.
In my repository, I inject the data sources using the injectable and the getit packages with
@injectable @LazySingleton (as: IJournalsRepository) class JournalsRepository implements IJournalsRepository { final JournalsRemoteDataSource journalsRemoteDataSource; final JournalsLocalDataSource journalsLocalDataSource; JournalsRepository(this.journalsLocalDataSource, this.journalsRemoteDataSource);
Those packages then create an instance of
JournalsRemoteDataSource
and ofJournalsRemoteDataSource
and inject it into the repository.The ObjectBox example shows for initialization
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(); } }
So I am lacking an idea on how an injector could initialize ObjectBox or how I could access the
objectBox
object from within the injectedJournalsRemoteDataSource
if I would initializeobjectBox
inMyApp()
(which is upstream to theHomePage
)PS: reopening the box in
JournalsRemoteDataSource
on every read/write event has a very poor performance========== UPDATE ========== supplementing my comment to @vaind
I have found your answer on this similar question in the meantime (not sure why I did not see it, initially). I hope to get this approach working here, too. However, I have still issues initializing the store. My prototype comes from Firestore and looks like this:
import 'package:firebase_auth/firebase_auth.dart'; import 'package:injectable/injectable.dart'; @module abstract class FirebaseInjectableModule { @lazySingleton FirebaseAuth get firebaseAuth => FirebaseAuth.instance; }
though I do not understand where the getter
firebaseAuth
comes from and haven't found any explanation, yet. Anyways, I adapted that toimport '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(); }
and use this with
@LazySingleton (as: ILocalDataSource) class ObjectBoxDataSource implements ILocalDataSource { final Store _store; final Box<JournalOboxEntity> _box; ObjectBoxDataSource(this._store) : _box = _store.box();
Besides
final Store _store
being grey in IntelliJ (unused variable), I receive the errorYou 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'
-
w461 over 2 yearsHey vaind, thanks for your answer. I am refactoring my code to the splendid tutorial of Reso Coder regarding DDD and unfortunately, I am also not familiar with those packages (why I moving from one problem to the next, currently). I am following a different approach based on another answer of yours and have updated my question accordingly. Maybe you have an idea, how to overcome the new hurdles...
-
w461 over 2 yearsgot it, solution follows