MVVM и репозиторий Вопрос - PullRequest
       4

MVVM и репозиторий Вопрос

5 голосов
/ 08 декабря 2010

Допустим, у меня есть два представления в моем приложении, MemberListView и MemberEditView.Они связаны с их перспективными viewModel, MemberListViewModel и MemberEditViewModel.Модели общаются с классом репозитория MemberRepository, в котором есть методы CRUD для класса члена.

В форме MemberEditView у меня есть несколько раскрывающихся списков, которые отображают такие элементы, как Status (Active / Inactive / Pending), членыторговый код и т. д. Они являются объектами ObservableCollection в моей viewModel и связаны с ComboBox на представлении.Должен ли MemberRepository обрабатывать запросы на получение списков каждого из них для отображения?

Что если в MemberEditView у меня есть сетка, отображающая все задания, которые член имел за эти годы.Если пользователь дважды щелкает одно из заданий, он вызывает JobHistoryEditView для отображения информации о задании и имеет JobHistoryViewModel.Должен ли MemberRepository позаботиться о методах CRUD JobHistory или у меня должен быть отдельный репозиторий JobHistory?

1 Ответ

2 голосов
/ 11 декабря 2010

Большинство приложений MVVM имеют такую ​​архитектуру:

View -> ViewModel -> Model -> Repository

Я недавно поддерживал вариант:

View -> ViewModel <- Presenter -> Model -> Repository

(где A -> B означает «A знает о B», но B не знает об A.)

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

public class MemberEditTask
{
    private readonly Member _member;

    public MemberEditTask(Member member, IRepository repository)
    {
        this._member = member;
        this.StatusChoices = repository.GetPossibleMemberStatuses(member);
    }

    public ReadOnlyCollection<MemberStatus> StatusChoices { get; private set; }

    public MemberStatus Status
    {
        get { return this._member.Status; }
        set
        {
            if(!this.StatusChoices.Contains(value)) 
            { 
                throw new ArgumentOutOfRangeException();
            }
            this._member.Status = value;
        }
    }
}

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

Итак, с учетом этого класса класс ViewModel выглядит следующим образом:

public class MemberEditViewModel : ViewModelBase
{
    private readonly MemberEditTask _task;

    public MemberEditViewModel(MemberEditTask task)
    {
        this._task = task;
    }

    public IEnumerable<MemberStatus> StatusChoices 
        { get { return this._task.StatusChoices; }

    public MemberStatus Status 
    {
        get { return this._task.Status; }
        set
        {
            this._task.Status = value;
            NotifyAllPropertiesChanged();
        }
    }
}

В этом случае, для очень простого удобства, просто поверьте, что NotifyAllPropertiesChanged - это защищенный метод ViewModelBase, который использует отражение, чтобы вызвать событие PropertyChanged для всех открытых свойств ViewModel. , :) Это, конечно, излишне, но это ведет к более важному моменту ...

Это почти глупый пример, потому что в этом случае MemberEditViewModel не требуется. Если параметр View является единственной настройкой Status, тогда на самом деле нет необходимости вызывать событие измененного свойства! Конечно, в реальном мире у вас будет больше свойств и будут взаимодействия. Причина существования ViewModel состоит в том, чтобы уведомлять потребителей об изменении его свойств, связанных с представлением, чего не делает Модель (и, по моему мнению, этого не должно). (ViewModel также имеет дополнительную специфичную для View логику для поддержки анимации и т. Д.)

Итак, вернемся к вашему вопросу ... является ли MemberRepository ответственным за выполнение получения статусов, не имеет значения с точки зрения ViewModel, потому что репозиторий является службой, используемой моделью. Модель - это сервис, используемый ViewModel. Сделайте свою Модель задачи / рабочего процесса / процесса / того, что выставляет список параметров состояния.

Извините, если это было многословно.

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