MVVM где поставить Data Access Layer? - PullRequest
28 голосов
/ 11 ноября 2009

Я изучаю шаблон проектирования MVFM в WPF. Но я не уверен, куда поместить код доступа к данным?

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

Это общий подход? Я чувствую, что здесь чего-то не хватает!

Спасибо

Ответы [ 6 ]

42 голосов
/ 12 ноября 2009

Вот как я организовывал свои проекты MVVM с LINQ:

Модель - Я думаю о Модели как о состоянии системы. Он предоставляет интерфейс для данных и отслеживает состояние системы. Модель не знает о ViewModel или View - она ​​просто предоставляет открытый интерфейс для своих данных и различных событий, чтобы потребители (обычно ViewModels) знали, когда изменилось состояние.

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

Вид - Вид - это фактический внешний вид пользовательского интерфейса. Он содержит все встроенные и настраиваемые элементы управления, их расположение и стиль. Он знает о ViewModel, но только с целью привязки к его свойствам.

Шлюз - Это часть, которая напрямую касается вашего вопроса. Шлюз (по сути, это мой способ сказать «DataAccessLayer») - это отдельный отдельный слой. Он содержит весь код (включая запросы LINQ) для CRUD или выбора, вставки, обновления и удаления данных из / в ваш источник данных (база данных, файл XML и т. Д.). Он также предоставляет открытый интерфейс для Модели, позволяя модели сосредоточиться на поддержании состояния системы, не заботясь о деталях (то есть запросах), необходимых для обновления источника данных.

Классы DataAccess - В C # это очень простые классы, которые моделируют ваши элементарные объекты данных. Когда вы выбираете что-то с помощью запроса LINQ, вы обычно создаете IEnumerable<T> или List<T>, где T является одним из ваших объектов данных. Примером объекта данных будет:

public class Person
{
    public string Name { get; set; }
    public int Age { get; set; }
}

Большим преимуществом такого дизайна является то, что он действительно разделяет ваши заботы. У всего есть специализированная работа, и (обычно) довольно легко узнать, что и куда идет.

Недостатком является то, что это может быть излишним для небольших проектов. В итоге вы создаете много инфраструктуры для общедоступных интерфейсов, которые в основном пропускают одно желание через несколько уровней. Таким образом, у вас может получиться такой сценарий: [пользователь нажимает Submit, ViewModel сообщает Model для AddNewPerson, Model сообщает Gateway to InsertPerson] вместо такого сценария [пользователь нажимает Submit, ViewModel добавляет новую запись в базу данных напрямую].

Надеюсь, это поможет.

12 голосов
/ 11 ноября 2009

Я бы добавил еще один слой, по сути, вам нужна фабрика данных. Вы хотите создать набор классов, которые будут CRUD для базы данных и возвращать чистые объекты POCO в ViewModel.

Хорошим примером может служить книга Nerd Dinner . Он охватывает MVC, а не MVVM, но шаблоны очень похожи, и способ, которым они получают доступ к данным в этом решении, был бы хорошей отправной точкой.

Надеюсь, это поможет.

11 голосов
/ 11 ноября 2009

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

Используйте какой-нибудь картограф для сопоставления вашей модели представления (виртуальная машина в MVVM) с вашей моделью (первая M). Новые объекты в вашей модели могут быть созданы с использованием фабричного шаблона. После создания вы можете сохранить их в базе данных, используя шаблон хранилища. Затем репозитории будут представлять ваш уровень доступа к данным. В вашем хранилище вы можете использовать O / R mapper, например, NHibernate или Entity Framework.

EDIT:
Я вижу, что GraemeF предлагает добавить в модель код доступа к данным. Это НЕ хороший подход, так как это заставит вас обновить модель вашего домена, если вы перейдете, например, из SQL Server в Oracle или XML-файлы. Объектам домена не нужно беспокоиться о том, как они сохраняются. Шаблон хранилища изолирует домен от его постоянства.

7 голосов
/ 11 ноября 2009

MVVM означает Модель , Вид и ViewModel . Часть, которую вам не хватает, - это Модель, в которой живет ваш код доступа к данным.

ViewModel берет модель и представляет ее представлению для отображения, поэтому обычно у вас будет что-то вроде этого:

class PersonModel : IPerson
{
    // data access stuff goes in here
    public string Name { get; set; }
}

class PersonViewModel
{
    IPerson _person;

    public PersonViewModel(IPerson person)
    {
        _person = person;
    }

    public Name
    {
        get { return _person.Name; }
        set { _person.Name = value; }
    }
 }

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

2 голосов
/ 20 февраля 2010

WPF Application Framework (WAF) содержит пример приложения, в котором показано, как шаблон Model-View-ViewModel (MVVM) можно использовать в сочетании с Entity Framework.

1 голос
/ 11 ноября 2009

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

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