Должен ли я использовать DTO в качестве моделей данных в MVVM? - PullRequest
11 голосов
/ 27 апреля 2010

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

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

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

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

Ответы [ 3 ]

5 голосов
/ 28 апреля 2010

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

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

Насколько я понимаю, существует несоответствие между уровнями приложения, которое является вашим Модель предметной области, вероятно, выглядит аналогично вашей реляционной модели, с небольшими, но существенными отличиями. Существует также несоответствие между моделью предметной области и вашим DTO (объекты могут быть сведены, вычисленные свойства и т. д., ...). Соблазнительно привязывать напрямую к DTO, поскольку они, вероятно, предназначены для того, чтобы иметь то, что вам нужно для конкретной операции, однако существует также несоответствие между DTO и тем, что необходимо представлению для достижения желаемого результата. Вот тут-то и появляется модель представления. Модель представления отвечает за передачу свойств DTO в представление, отвечает за оповещение представления о наличии ошибок проверки и направляет команды соответствующему обработчику (Сохранить, Удалить и т. Д.). ...).

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

// 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. По сути, все поведение вашего пользовательского интерфейса должно быть выражено в терминах вашей модели представления.

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

2 голосов
/ 27 апреля 2010

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

1 голос
/ 28 апреля 2010

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

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

...