flutterdartasynchronoussingletondart-null-safety

How to implement a singleton with async initialisation and null safety in dart?


I need a Singleton for the shared preferences which has async initialisation but also works with null safety. Usually I used the following singleton implementation, but what is the best way to have a singleton which works with null safety?

class SharedPrefs {
static SharedPrefs _instance;
static Future<Null> _mutex;

static Future<SharedPrefs> getInstance() async {
  if (_mutex != null) {
    await _mutex;
  }
  var completer = Completer<Null>();
  _mutex = completer.future;

  if (_instance == null) {
    _instance = SharedPrefs();
    await _instance.init();
  }

  completer.complete();
  _mutex = null;

  return _instance;
}

SharedPreferences prefs;

SharedPrefs();

Future<SharedPrefs> init() async {
  SharedPreferences prefs = await SharedPreferences.getInstance();
  return this;
}

dynamic get(String key) {
  return prefs.getString(key);
}

Future<bool> put(String key, dynamic value) async {
  return await prefs.setString(key,value);
}
}

Solution

  • Here you go:

    class SharedPreferencesProvider {
      static SharedPreferencesProvider? _instance;
      final SharedPreferences _sharedPreferences;
    
      static Future<SharedPreferencesProvider> getInstance() async {
        if (_instance == null) {
          final sharedPreferences = await SharedPreferences.getInstance();
          _instance = SharedPreferencesProvider._(sharedPreferences);
        }
        return _instance!;
      }
    
      SharedPreferencesProvider._(SharedPreferences sharedPreferences)
          : _sharedPreferences = sharedPreferences;