Home > OS >  How to recreate singleton instance if different params are passed to the constructor in dart
How to recreate singleton instance if different params are passed to the constructor in dart

Time:10-22

I gathered the following understanding for creating a singleton in dart with params

class Foo extends ChangeNotifier {
  late String channel;

  void instanceMemberFunction () {
      print('Foo created with channel $channel')
  }

  static final Foo _instance = Foo._internal();

  Foo._internal() {
    instanceMemberFunction();
  }

  factory Foo({
    required String channel
  }) {
    _instance.channel = channel;
    return _instance;
  }
}

and I am calling the instance like so

Foo({channel: "bar"})

Now I want to have some working that if I use

Foo({channel: "baz"})

Then a new instance is created and it's okay in that case to destroy the old one. How can I achieve this in dart?

CodePudding user response:

It seems like you've copied some existing example for creating a singleton without fully understanding what it's doing and why. The core parts are:

  1. The single instance is stored in a global or static variable.
  2. The class has one or more public factory constructors that returns that global/static variable, initializing it if necessary.
  3. All other constructors for the class are private to force consumers to go through the factory constructors.

Therefore, if you want your factory constructor to replace its singleton based on its argument, you need to:

  1. Make your factory constructor check if the argument is appropriate for the existing instance. If it is, return the existing instance. If not (or if there is no existing instance), create and return a new instance.
  2. Since you need to check if the existing instance is initialized, make it nullable. (You alternatively could initialize it to a non-null sentinel value, e.g. Foo._internal(channel: '').
  3. Pass the argument along to the private constructor.
class Foo extends ChangeNotifier {
  final String channel;

  void instanceMemberFunction () {
    print('Foo created with channel $channel');
  }

  static Foo? _instance;

  Foo._internal({required this.channel}) {
    instanceMemberFunction();
  }

  factory Foo({required String channel}) {
    if (channel != _instance?.channel) {
      _instance = Foo._internal(channel: channel);
    }
    return _instance!;
  }
}
  • Related