How properly use the ObjectBox flutter store opening and closing?

Issue

I am looking to define best development practices with Flutter and ObjectBox (1.1.1 -> Flutter).

I would like to set up an architecture composed of Repository to implement my query functions on objects stored in the database. Here is an example for an Object Person. Repositories will mainly be called from viewModels.

import 'package:flutter_app_best_practice/data/person_repository_interface.dart';
import 'package:flutter_app_best_practice/model/person.dart';
import 'package:flutter_app_best_practice/objectbox.g.dart';
import 'package:objectbox/objectbox.dart';

class PersonRepository implements IPersonRepository{
  var _store;
  late Box _box;

  @override
  Future<List<Person>>? getPeople() {
    List<Person> list = _box.getAll() as List<Person>;
    return Future.value(list);
  }

  @override
  Future<void>? addPerson(String name, int age) async {
    Person person = new Person();
    person.name = name;
    person.age = age;
    _box.put(person);  // Add
    return;
  }

  @override
  Future<void>? initialize() async {
    // Future<Store> openStore() {...} is defined in the generated objectbox.g.dart
    openStore().then((Store store) {
      _store = store;
    });

    _box = _store.box<Person>();

    return;
  }
}

Here are my questions:

  • Or call _store.close with this architecture ?
  • Instead of having an Initialize function, would it be better to open the store before each transaction and then close it after the transaction is complete?
  • Are there examples of a similar structure using this latest version of objectBox (using openStore (). Then ((Store store))

How do you think about this implementation :


class PersonRepository implements IPersonRepository {

  @override
  Future<List<Person>>? getPeople() async {
    late List<Person> persons;

    await openStore().then((Store store) {
      var _box = store.box<Person>();
      persons = _box.getAll();
      store.close();
    });

    return Future.value(persons);
  }

  @override
  Future<void>? addPerson(String name, int age) async {

    await openStore().then((Store store) {
      var _box = store.box<Person>();
      Person person = new Person();
      person.name = name;
      person.age = age;
      _box.put(person);  // Add
      store.close();
    });
    
    return;
  }
}

Solution

Or call _store.close with this architecture ?

You can ignore Store.close() in normal applications without excessive amount of background operations.

Instead of having an Initialize function, would it be better to open the store before each transaction and then close it after the transaction is complete?

No, opening a store is "rather" costly so you shouldn’t do it on every store access – it’s just going to slow things down for you and there’s no benefit.

Are there examples of a similar structure using this latest version of objectBox (using openStore (). Then ((Store store))

There’s an example in the objectbox package itself, albeit with a different code structure: https://github.com/objectbox/objectbox-dart/blob/main/objectbox/example/flutter/objectbox_demo/lib/main.dart#L79


To give you one example what you could do, while keeping the level of abstraction your code tries to do:

class PersonRepository implements IPersonRepository {
  final Store _store;
  final Box<Person> _box;

  PersonRepository(this._store) : _box = _store.box() {}

  @override
  Future<List<Person>>? getPeople() {
    List<Person> list = _box.getAll() as List<Person>;
    return Future.value(list);
  }

  @override
  Future<void>? addPerson(String name, int age) async {
    Person person = new Person();
    person.name = name;
    person.age = age;
    _box.put(person);  // Add
    return;
  }
}

abstract class IDatabaseRepositories {
  IPersonRepository get people;
}

class ObjectBoxRepositories implements IDatabaseRepositories {
  final Store _store;

  final PersonRepository people;

  static Future<IDatabaseRepositories> create() async =>
      ObjectBoxRepositories._(await openStore());

  ObjectBoxRepositories._(this._store) : people = PersonRepository(_store);
}

Answered By – vaind

Answer Checked By – Robin (FlutterFixes Admin)

Leave a Reply

Your email address will not be published.