передача параметра в singleton и определение члена на основе этого - PullRequest
0 голосов
/ 04 августа 2020

Мне нужно передать параметр синглтону и определить член класса на основе переданного параметра.

Это код, который я использую, который на самом деле не работает:

class MyService {
  static final MyService _singleton = ImapService._internal();

  String level;
  MyClass _client;

  factory MyService({level = 'HIGH'}) {
    _singleton.level = level;

    return _singleton;
  }

  MyService._internal() {
    if (level == 'LOW') {
      _client = new Class1();
    } else {
      _client = new Class2();
    }
  }
}

Проблема в том, что функция MyService._internal() всегда вызывается перед factory, поэтому переменная level всегда имеет значение null в функции, а мой код никогда не входит в инструкцию If.

Ответы [ 2 ]

1 голос
/ 04 августа 2020

Я думаю, что самое простое решение, которое вы можете сделать, это следующее (на основе последних обновлений требований в комментариях: «все в порядке, если синглтон остается таким же после первого экземпляра. В следующих случаях он просто может игнорировать аргумент уровня . "):

class MyService {
  static MyService _singleton;

  MyClass _client;

  factory MyService({String level = 'HIGH'}) =>
      _singleton ??= MyService._internal(level);

  MyService._internal(String level) {
    if (level == 'LOW') {
      _client = new Class1();
    } else {
      _client = new Class2();
    }
  }
}
1 голос
/ 04 августа 2020

Вам нужен синглтон с изменяемым состоянием. Это несколько разумно.

Если вы go с состоянием в экземпляре, вам нужны допустимые начальные значения. Что-то вроде:

class MyService {
  static final MyService _singleton = MyService._internal();
  String _level;
  MyClass _clientCache;
  String get level => level;
  set level(String level) {
    if (_level != level) {
      _level = level;
      _clientCache = level == "LOW" ? Class1() : Class2();
    }
  }
  factory MyService({String level = "HIGH"}) => _singleton..level = level;
  MyService._internal() : _level = "HIGH", _clientCache = Class1();
}

Тогда вы также можете просто сохранить это состояние в глобальной переменной. Это позволит вам выполнить ленивую инициализацию геттера _class.

Что-то вроде:

class MyService {
  static final MyService _singleton = const MyService._internal();

  static String _level = "HIGH";
  static MyClass _clientCache = _classFromLevel(_level);

  String get level => _level;
  void set level(String level) {
    if (_level != level) {
      _level = level;
      _clientCache = _classFromLevel(level);
    }
  }

  MyClass _client => _clientCache;

  factory MyService({level = 'HIGH'}) => _instance..level = level;

  const MyService._internal();

  static MyClass _classFromLevel(String level) =>
    level == "LOW" ? Class1() : Class2();
}

(Учтите, нужен ли вам действительно синглтон. Изменяемый синглтон object - это просто прославленная глобальная переменная со всеми присущими ей проблемами.)

...