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

Problem in registering database connection class #296

Closed roshtha closed 1 year ago

roshtha commented 2 years ago

Hello all,

I am getting problems will be registering sqflite database singleton connection class DatabaseCon .

I register classes like

final locator = GetIt.instance;
Future<void> initAppModule() async {
  final sharedPrefs = await SharedPreferences.getInstance();

  locator.registerLazySingleton<SharedPreferences>(() => sharedPrefs);

  locator.registerLazySingleton<AppPreferences>(() => AppPreferences(locator()));

  locator.registerLazySingletonAsync <DatabaseCon>(() async => DatabaseCon.create()); //, signalsReady: false

  locator.registerFactoryParam<Students,String,String>((param1, param2) => Students(name: param1, email: param2));
  locator.allReady();
}
resetModules() {
  locator.reset(dispose: false);
  initAppModule();  
}

And the DatabaseCon class

class DatabaseCon   {
  late Database _database;

  DatabaseCon._();

  //public factory to call private constructor
  static Future<DatabaseCon> create() async 
  {
    DatabaseCon dbConn =  DatabaseCon._();
    dbConn._database = await dbConn._init();
    locator.signalReady(dbConn);
    return dbConn;
  }

  Future<Database> get database async {
    return _database;
  }

   Future<Database> _init() async{
      var path = join(await getDatabasesPath(), "sampledb.db");
      print("path=${path}");

      var exists = await databaseExists(path);
      //Not for production. For checkon versions and upgrade, if necessary
      await deleteDatabase(path);
      exists = await databaseExists(path);
      if (!exists) {
          // Make sure the parent directory exists
          try {
            await Directory(dirname(path)).create(recursive: true);
          } 
          catch (_) {
            print("exception thrown");
          }
          ByteData data = await rootBundle.load(join("assets", "sampledb.db"));

          List<int> bytes = data.buffer.asUint8List(data.offsetInBytes, data.lengthInBytes);

          // Write and flush the bytes written
          await File(path).writeAsBytes(bytes, flush: true);
      }
      else
      {
        print("Opening already copied database file");
      }

      return await openDatabase(     
       join(await getDatabasesPath(), "sampledb.db") ,
       version: 1       
     );
  }
}
══╡ EXCEPTION CAUGHT BY WIDGETS LIBRARY ╞═══════════════════════════════════════════════════════════
The following assertion was thrown building MyHomePage(dirty, state: _MyHomePageState#ab599):
You tried to access an instance of DatabaseCon that is not ready yet
'package:get_it/get_it_impl.dart':
Failed assertion: line 404 pos 9: 'instanceFactory.isReady'

The relevant error-causing widget was:
  MyHomePage MyHomePage:file:///F:/Chapter4/samples/sample/lib/main.dart:32:19

Also please help in understanding the statement locator.registerLazySingleton<AppPreferences>(() => AppPreferences(locator()));

Why locator() is used in AppPreferences(locator())).

Thanks.

escamoteur commented 1 year ago

Sorry for the late response, I had to take a longer break due to health issues. Have you solved your problem in the meantime?