Как правильно получить пользовательский ввод из середины метода модели в архитектуре Model-View-Viewmodel? - PullRequest
7 голосов
/ 20 мая 2009

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

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

И что еще хуже, я хочу сделать это синхронно, потому что я хочу, чтобы мой алгоритм ответа был в одном месте, а не разбит на несколько обратных вызовов с неясными обязанностями «кто звонит, кто».

Просто что-то вроде

HandleMessage(Message msg){
    string reply;
    if (msg.type == 1) {
        reply = ...
    } else {
        string question = msg...
        reply = ShowModalDialog(question); // MVVM violation!
    }
    sender.Send(reply);
}

но я не хочу вызывать view или viewmodel из модели, так как модель должна быть многократно используемой и тестируемой - я не хочу, чтобы в каждом тестовом прогоне появлялись диалоговые окна, и это было бы нарушением MVVM! Нет событий (насколько я знаю, они односторонние и не имеют обратного канала для получения ответа на источник события) или привязки к данным, поскольку это будет асинхронно.

Это выполнимо? Этот вопрос я задал нескольким сторонникам разработки, управляемым тестированием, и до сих пор не получил практически пригодного ответа. Тем не менее, потребность в некотором дополнительном вводе в середине обработки довольно распространена.

Спасибо!

РЕДАКТИРОВАТЬ: это логика приложения, поэтому она явно принадлежит модели, и даже если бы в этом случае это не так, я хотел бы узнать решение для случаев, когда мне действительно нужен ввод пользователя в середине бизнес-логики рутина в модели.

Ответы [ 3 ]

4 голосов
/ 20 мая 2009

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

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

Вот описание работы сервисов в PRISM.

Так что конкретно в вашем случае я бы создал какой-то IOC, зарегистрировал в нем службу запросов, затем на проходе ViewModel в IOC, а затем использовал IOC для получения службы запросов и использовал ее для запросов пользователя. Больше работы? Конечно. Но это означает, что вы можете заменить службу запросов другой реализацией для тестирования, просто заменив ее в IOC.

MVVM + Services = Максимальная мощность!

1 голос
/ 20 мая 2009

Я не знаю, соответствует ли эта идея принципам MVVM, но ... я бы инкапсулировал функциональность диалога как сервис (на который ссылается интерфейс). Реализация сервиса будет на уровне пользовательского интерфейса, но для целей тестирования вы просто «макетируете» интерфейс.

0 голосов
/ 20 мая 2009

На самом деле, это не ВСЕ относится к логике приложения.

Кажется, у вас есть 2 разных "взгляда". Первоначальный (данные поступают по сети) и второй (диалоговое окно подтверждения).

Модель должна определить, что необходимо отобразить новое представление, дать сигнал представлению для его отображения, а затем ответить на входные данные этого представления.

Не пытайтесь сделать все это за один шаг.

...