fluttercommunity / get_it

Get It - Simple direct Service Locator that allows to decouple the interface from a concrete implementation and to access the concrete implementation from everywhere in your App. Maintainer: @escamoteur
https://pub.dev/packages/get_it
MIT License
1.36k stars 149 forks source link

Question: Is there a way to make getIt not update the singleton? #381

Closed piperun closed 1 month ago

piperun commented 1 month ago

Hi! I'm using Signal together with get_it to effectively do the same task as Provider/Riverpod does, now with Provider it was very straight forward and for the most part the same can be said about Signal+get_it.

With one exception (I had a similar issue with Riverpod): It'll update itself 2 times and as a result technically recreate the instance 2 times.

Normally this isn't an issue for objects/values that aren't strictly meant to be instanced once, but I'm using drift/SQL queries which you do not want to have more than 1 instance at a time since otherwise you'll get race conditions.

And I have no clue as to why exactly get_it decides to it (or if it's signal, which I doubt since when trying with global signals never stumble upon this, and I could replicate the same issue in riverpod).

[log] signal created: [1|null] => Instance of 'AsyncLoading<AppDatabaseHandler>'
[log] computed created: [2|null]
[log] signal created: [3|null] => Instance of 'AsyncLoading<BaseDir>'
[log] computed created: [4|null]
[log] signal created: [5|null] => Instance of 'AsyncLoading<ConfigDatabaseFileHandler>'
[log] computed created: [6|null]
[log] signal created: [7|null] => Instance of 'FolderStepper'
[log] signal created: [8|null] => Instance of 'FolderDraft'
[log] computed updated: [4|null] => Instance of '_ControllerStream<BaseDir>'
[log] computed updated: [6|null] => Instance of '_ControllerStream<ConfigDatabaseFileHandler>'
[log] signal updated: [3|null] => Instance of 'AsyncData<BaseDir>'
[log] computed updated: [6|null] => Instance of '_ControllerStream<ConfigDatabaseFileHandler>'
[log] signal updated: [5|null] => Instance of 'AsyncData<ConfigDatabaseFileHandler>'

locator.dart

final locator = GetIt.I;

void locatorSetup() {
  locator.registerSingleton<FutureSignal<ConfigDatabaseFileHandler>>(
      futureSignal(initializeConfigDatabaseFileHandler));
}

signal.dart

Future<ConfigDatabaseFileHandler> initializeConfigDatabaseFileHandler() async {
  final baseDir =
      await locator.get<FutureSignal<BaseDir>>().future;

  final databaseName = "config.sqlite";
  final databasePath = baseDir.configDir;

  final configDatabase = ConfigDatabaseFileHandler(
    databaseLocation: DatabaseLocation(
      databaseDirectory: databasePath,
      databaseFilename: databaseName,
    ),
  );
  configDatabase.createDatabase(setupOnInit: true); // <- this only creates the database & populate it with preexisting data

  return configDatabase;
}

I'm happy to provide any additonal code needed.

piperun commented 1 month ago

Apologizes, turns out it's all due to FutureSignal & get_it is not at fault.