How do you build a Singleton in Dart? How do you build a Singleton in Dart? dart dart

How do you build a Singleton in Dart?


Thanks to Dart's factory constructors, it's easy to build a singleton:

class Singleton {  static final Singleton _singleton = Singleton._internal();  factory Singleton() {    return _singleton;  }  Singleton._internal();}

You can construct it like this

main() {  var s1 = Singleton();  var s2 = Singleton();  print(identical(s1, s2));  // true  print(s1 == s2);           // true}


Here is a comparison of several different ways to create a singleton in Dart.

1. Factory constructor

class SingletonOne {  SingletonOne._privateConstructor();  static final SingletonOne _instance = SingletonOne._privateConstructor();  factory SingletonOne() {    return _instance;  }}

2. Static field with getter

class SingletonTwo {  SingletonTwo._privateConstructor();  static final SingletonTwo _instance = SingletonTwo._privateConstructor();  static SingletonTwo get instance => _instance;  }

3. Static field

class SingletonThree {  SingletonThree._privateConstructor();  static final SingletonThree instance = SingletonThree._privateConstructor();  }

How to instantiate

The above singletons are instantiated like this:

SingletonOne one = SingletonOne();SingletonTwo two = SingletonTwo.instance;SingletonThree three = SingletonThree.instance;

Note:

I originally asked this as a question, but discovered that all of the methods above are valid and the choice largely depends on personal preference.


I don't find it very intuitive reading new Singleton(). You have to read the docs to know that new isn't actually creating a new instance, as it normally would.

Here's another way to do singletons (Basically what Andrew said above).

lib/thing.dart

library thing;final Thing thing = new Thing._private();class Thing {   Thing._private() { print('#2'); }   foo() {     print('#3');   }}

main.dart

import 'package:thing/thing.dart';main() {  print('#1');  thing.foo();}

Note that the singleton doesn't get created until the first time the getter is called due to Dart's lazy initialization.

If you prefer you can also implement singletons as static getter on the singleton class. i.e. Thing.singleton, instead of a top level getter.

Also read Bob Nystrom's take on singletons from his Game programming patterns book.