передача исходных данных в одноэлементную фабрику в dart

#dart

#дротик

Вопрос:

Я хотел бы передать некоторую начальную информацию в синглтон в dart. К сожалению, информация, к которой я хотел бы получить доступ, равна нулю (см. Вывод dartpad ниже). Кажется, что я получаю новый экземпляр моего объекта, а не синглтон, но я не могу обмозговать это. Есть какие-нибудь идеи?

 ElmCommandProvider.fromMetaData
ElmCommandProvider._internal()
ElmCommandProvider._init
ElmCommandProvider()
null
 

Это код, который можно вставить в DartPad

 class Command {
  Command(this.i);
  final int i;
}

class MetaData {
  MetaData(this.i);
  final int i;
}

class ElmCommandProvider {
  List<Command> commandsList;
  bool _lock = false;

  static Map<String, MetaData> _metaDataPool;

  factory ElmCommandProvider.fromMetaData(Map<String, MetaData> metaDataPool) {
    print('ElmCommandProvider.fromMetaData');
    assert(!_singleton._lock, "it's a singleton that can't re-defined");
    ElmCommandProvider._metaDataPool = metaDataPool;
    _singleton._lock = true;
    ElmCommandProvider._init();
    return _singleton;
  }

  factory ElmCommandProvider() {
    print('ElmCommandProvider()');
    return _singleton;
  }

  static final ElmCommandProvider _singleton =
      new ElmCommandProvider._internal();

  ElmCommandProvider._internal() {
    print('ElmCommandProvider._internal()');
  }
  ElmCommandProvider._init() {
    print('ElmCommandProvider._init');
    commandsList =
        _metaDataPool.values.map((bloc) => Command(bloc.i)).toList();
    
  }
}

void main() {
  ElmCommandProvider.fromMetaData({'1': MetaData(1), '2': MetaData(2)});
  print( ElmCommandProvider().commandsList);
}
 

Ответ №1:

_init() не должен быть конструктором. Или, по крайней мере, в этом нет необходимости, и это сбивает вас с толку. Он должен быть изменен на статический метод или метод частного экземпляра.

Когда вы делаете commandsList= in ElmCommandProvider._init() , commandsList ссылается на переменную commandsList экземпляра в новом ElmCommandProvider объекте, который вы создаете с помощью конструктора. Вероятно, вы на самом деле имеете в виду изменить синглтоны commandsList , так что вам следовало бы делать singleton.commandsList = , а не просто commandsList = .

Пример рабочего кода со статическим методом:

 class Command {
  Command(this.i);
  final int i;
}

class MetaData {
  MetaData(this.i);
  final int i;
}

class ElmCommandProvider {
  List<Command> commandsList;
  bool _lock = false;

  static Map<String, MetaData> _metaDataPool;

  factory ElmCommandProvider.fromMetaData(Map<String, MetaData> metaDataPool) {
    print('ElmCommandProvider.fromMetaData');
    assert(!_singleton._lock, "it's a singleton that can't re-defined");
    ElmCommandProvider._metaDataPool = metaDataPool;
    _singleton._lock = true;
    _init();
    return _singleton;
  }

  factory ElmCommandProvider() {
    print('ElmCommandProvider()');
    return _singleton;
  }

  static final ElmCommandProvider _singleton =
      new ElmCommandProvider._internal();

  ElmCommandProvider._internal() {
    print('ElmCommandProvider._internal()');
  }
  static _init() {
    print('ElmCommandProvider._init');
    _singleton.commandsList =
        _metaDataPool.values.map((bloc) => Command(bloc.i)).toList();
    
  }
}

void main() {
  ElmCommandProvider.fromMetaData({'1': MetaData(1), '2': MetaData(2)});
  print( ElmCommandProvider().commandsList);
}
 

Пример рабочего кода с методом частного экземпляра:

 class Command {
  Command(this.i);
  final int i;
}

class MetaData {
  MetaData(this.i);
  final int i;
}

class ElmCommandProvider {
  List<Command> commandsList;
  bool _lock = false;

  static Map<String, MetaData> _metaDataPool;

  factory ElmCommandProvider.fromMetaData(Map<String, MetaData> metaDataPool) {
    print('ElmCommandProvider.fromMetaData');
    assert(!_singleton._lock, "it's a singleton that can't re-defined");
    ElmCommandProvider._metaDataPool = metaDataPool;
    _singleton._lock = true;
    _singleton._init();
    return _singleton;
  }

  factory ElmCommandProvider() {
    print('ElmCommandProvider()');
    return _singleton;
  }

  static final ElmCommandProvider _singleton =
      new ElmCommandProvider._internal();

  ElmCommandProvider._internal() {
    print('ElmCommandProvider._internal()');
  }
  void _init() {
    print('ElmCommandProvider._init');
    commandsList =
        _metaDataPool.values.map((bloc) => Command(bloc.i)).toList();
    
  }
}

void main() {
  ElmCommandProvider.fromMetaData({'1': MetaData(1), '2': MetaData(2)});
  print( ElmCommandProvider().commandsList);
}