Должен ли я использовать DTO в качестве моделей данных в MVVM?

В настоящее время я работаю над тем, что станет моим первым реальным набегом на использование MVVM и читал различные статьи о том, как лучше всего его реализовать.

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

Очевидно, что проблемы с INotifyPropertyChanged не будут корректно работать на стороне сервера, так как нет ViewModel для связи, но до тех пор, пока мы будем осторожны в построении наших собственных объектов модели домена из моделей данных на сервисном уровне, а не работая с моделями данных на стороне сервера, я не думаю, что это должна быть большая проблема.

Я не нашел слишком много информации об этом подходе в своем чтении, поэтому я хотел бы знать, является ли это довольно стандартным, это просто считается де-факто способом MVVM в многоуровневом Окружающая среда? Если бы у меня было совершенно неправильное представление о вещах, тогда были бы также оценены мысли о других подходах.

Ответ 1

Я не эксперт в этом. У меня был такой же сценарий. Я согласен с вами в том, что это довольно перебор. Я использую это решение довольно долгое время и не сталкивался с какими-либо проблемами. INotifyPropertyChanged не является большой проблемой для меня, так как ничто на стороне сервера не будет подписано на событие PropertyChanged. Если вы будете использовать наследование в своих моделях данных, то все они должны быть сериализованы. В моем сценарии у меня есть два базовых класса для моделей данных: один, который используется для передачи данных, а другой нет.

Ответ 2

Вы можете использовать любую модель, с которой вам комфортно, да, для всех ваших свойств потребуется поведение INotifyPropertyChanged. Как это повлияет на уровень сервиса полностью вниз к вашей реализации.

Я предполагаю, что вы считаете, что привязываетесь к своему DTO в своем представлении?

Как я вижу, существует несоответствие импеданса между слоями приложения, то есть ваш Доменная модель, вероятно, выглядит симпатичной для вашей реляционной модели с небольшими, но важными отличиями. Есть также несоответствие между моделью домена и вашим DTO (объекты могут быть сплющены, вычисленные свойства и т.д.). Это соблазн связать непосредственно с DTO, поскольку они, вероятно, предназначены для того, чтобы иметь то, что вам нужно для конкретной операции, однако также существует несоответствие импеданса между DTO и тем, что необходимо для представления, чтобы достичь желаемого результата. Здесь появляется модель просмотра. Модель представления несет ответственность за проксирование свойств DTO для представления, она отвечает за то, чтобы дать представление знать, есть ли ошибки проверки, и направляет команды соответствующему обработчику (Save, Delete и т.д.).,...).

Я пытаюсь настроить вещи следующим образом:

// POCO object. Serializable.
public class AddressDto 
{    
   public int Id { get; set; }
   public string Street { get; set; }    
   public string City { get; set; }    
   public string Country { get; set; } 
}

// IDataErrorInfo for validation.
public class AddressViewModel : INotifyPropertyChanged, IDataErrorInfo
{
   private readonly AddressDto addressDto;

   public AddressViewModel(AddressDto addressDto)
   {
      this.addressDto = addressDto;      
   }

   public int Id { /* get and set for property changed event and update dto */ }
   public string Street { /* get and set for property changed event and update dto  */ }
   public string City { /* get and set for property changed event and update dto  */ }
   public string Country { /* get and set for property changed event and update dto  */ }
   ...

   // IDataErrorInfo implementation
}

public class EditAddressViewModel : INotifyPropertyChanged
{
   public AddressViewModel Address { /* get and set for property changed event */ }
   public ICommand Save { /* setup command */ }
   public ICommand Cancel { /* setup command */ }

   private void Save()
   {
   }

   private void Cancel()
   {
   }
}

Затем ваш EditAddressView будет привязан к EditAddressViewModel. В основном правило - это все ваше поведение пользовательского интерфейса должно быть выражено в терминах вашей модели представления.

Да, это означает дополнительную работу, howerver есть вещи, которые вы можете сделать, чтобы немного упростить вещи (генерация кода и т.д.). Я на самом деле работаю над библиотекой, целью которой является упрощение всего процесса MVVM с использованием свободного api. Проверьте это на http://fluentviewmodel.codeplex.com/

Ответ 3

Я решил иметь свойство "Модель" на моей модели ViewModel. В самой модели я уже реализую IPropertyNotifyChanged и IDataErrorInfo. В моей модели ViewModel я пропускаю свойства, где код просто "проваливается" к модели. Вместо этого представление связывается непосредственно с моделью для этих свойств.

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