Должен ли я зарегистрировать ViewModels в контейнере? - PullRequest
6 голосов
/ 22 октября 2010

Должен ли я зарегистрировать ViewModels в контейнере и решить оттуда?

Преимущества:

  1. Я могу выполнить некоторые действия, когда модель просмотра активирована
  2. Контейнер будет вводить зависимости для меня
  3. ???

Недостатки:

  1. Управление временем жизни ViewModel может быть сложным:
    • если я сделаю ViewModel singleton, я не смогу создать несколько элементов управления одного типа
    • если я сделаю ViewModel кратковременным, я легко могу оказаться в ситуации, когда у меня будет несколько разных экземпляров, когда я действительно ожидаю, что один и тот же экземпляр будет введен

Какой правильный ответ? Я бы предпочел зарегистрироваться, если бы мог уменьшить пожизненный недостаток.

Я использую Caliburn и Autofac, если это имеет значение.

Ответы [ 3 ]

5 голосов
/ 23 октября 2010

Контейнер - это экосистема, населенная объектами, которые он создает. Модели представлений взаимодействуют с этими обитателями и, следовательно, также являются частью экосистемы. Чтобы точно отразить это отношение, вы должны зарегистрировать модели представлений в контейнере.

Вы всегда должны использовать InstancePerDependency с моделями вида. Модель представления представляет состояние и поведение определенной части пользовательского интерфейса - это не зависящий от фреймворка аналог элемента управления. Точно так же, как вы не можете обычно размещать один и тот же экземпляр элемента управления в двух местах в дереве пользовательского интерфейса, вы также не можете повторно использовать один и тот же экземпляр модели представления.

Если бы вы могли, мы бы назвали это ViewsModel: -)

4 голосов
/ 22 октября 2010

Преимущества 2) мне достаточно, чтобы позволить контейнеру обрабатывать модели представления. Мы используем нашу собственную среду MVVM, в которой существует строгая взаимно-однозначная связь между экземплярами представления и экземплярами модели представления. Таким образом, 1) недостатки отсутствуют.

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

Кроме этого, существуют ли другие обстоятельства, когда вы ожидаете, что один экземпляр модели представления будет разделен между несколькими представлениями?

0 голосов
/ 23 октября 2010

Не уверен насчет autofac или Caliburn (может все еще применяться), но когда он придет в Unity Container, я зарегистрирую ViewModel только в том случае, если ...

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

container.RegisterType<MyViewModel>(new DisposeableInstanceLifetimeManager());
...
container.Resolve<MyViewModel>();  // here all dependencies will get injected
...
container.Dispose(); 

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

var child = container.CreateChildContainer();
child.RegisterInstance(model, new ContainerControlledLifetimeManager());
child.Resolve<MyViewModel1>();
child.Resolve<MyViewModel2>(); // both can share the model instance

(Примечание: в Unity все зависимости внедряются при использовании Resolve в ViewModel, даже если он не зарегистрирован в контейнере).

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

...