Устаревшие данные в MVVM ViewModels с внедрением зависимостей - PullRequest
5 голосов
/ 14 февраля 2012

В моем приложении WPF я использую шаблон MVVM вместе с внедрением зависимостей.

Модели представления, которые подготавливают данные из базы данных, вводят репозиторий в конструктор.Они также заполняют свойства данными из репозитория в конструкторе.

Все ViewModels создаются в статическом конструкторе класса ViewModelLocator, который все виды используют для привязки к своей ViewModel.

Это имеет следующие недостатки:

  1. Данные в представлениях никогда не обновляются, даже при их закрытии и повторном открытии, поскольку экземпляр ViewModel всегда одинаков.
  2. При открытии первого представления создаются все экземпляры ViewModel и загружаются данные, которые им требуются.из базы данных.

Я могу придумать два способа решения этих проблем:

  1. Заставить каждый ViewModel реализовать метод, который считывает данные из базы данных и инициализирует свойства- вместо того, чтобы делать это в конструкторе.Это потребует вызова этого метода каждый раз, когда открывается представление.Это вводит временную связь , которая мне не нравится.
  2. Реализуйте ViewModelLocator таким образом, чтобы он создавал запрошенную ViewModel каждый раз, когда вызывается соответствующее свойство в ViewModelLocator.Мне не нравится этот метод, потому что мой корень композиции не будет выполняться при запуске программы, но будет распространяться на все время существования экземпляра программы.

Есть ли другой способДля решения этой проблемы?Как другие решают это?

Ответы [ 2 ]

2 голосов
/ 14 февраля 2012

Реализуйте ViewModelLocator таким образом, чтобы он создавал запрошенную ViewModel каждый раз, когда вызывается соответствующее свойство в ViewModelLocator.

Это больше подход, который я обычно использую в подобных ситуациях. Однако вместо создания ViewModelLocator через DI ViewModels я создаю фабрики, которые создают ViewModel.

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

Это становится "решенным", по крайней мере частично, благодаря тому, что композиция создает фабрики вместо самих типов. Композиция происходит один раз при запуске, но создание может произойти в любое время рассматриваемой модели представления.

Например, используя MEF, вы можете переключать импорт для непосредственного использования ExportFactory<T> вместо их типа. Наряду с NonShared Creation Policy вы можете создавать ViewModels по мере необходимости и всегда работать со свежими данными, без проблем временного связывания.

0 голосов
/ 14 февраля 2012

Мой абстрактный ViewModelBase базовый класс требует абстрактного метода RefreshDataCore (). Этот метод можно вызвать вручную, вызвав функцию Refresh () для экземпляра ViewModel или установив флаг IsDirty. Когда ViewModel.IsVisible имеет значение true и IsDirty установлен, также будет вызван Refresh ().

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

Пример ниже. (Я упустил уведомления INPC для простоты)

public abstract class ViewModelBase
{
     //Pull your data from the repository here
     protected abstract void RefreshCore();
     public void Refresh()
     {
            RefreshCore();
            IsDirty = false;
     }

     private bool _isVisible = false;
     //DataBind this to the visibility of element "hosting" your view model
     public bool IsVisible
     {
         get { return _isVisible; }
         set
         {
              if (_isVisible == value)
                  return;


              _isVisible = value;
              if (IsVisible && IsDirty)
                   Refresh();
         }
     }

     private bool _isDirty = true;
     public bool IsDirty 
     {
         get { return _isDirty; }
         set 
         {
            if (_isDirty == value)
               return;

            _isDirty = value;
            if (IsVisible && IsDirty)
               Refresh();
         }
     }

}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...