2009-05-19 2 views
6

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

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

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

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

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

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

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

Спасибо!

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

ответ

3

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

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

Here's запись о том, как услуги работают в PRISM.

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

MVVM + Services = Ultimate Power!

+0

+1 для объяснения этого намного лучше, чем я. –

+0

Спасибо, это звучит как чистое решение, я прочитаю ссылки (спасибо за них!) –

0

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

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

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

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

+0

Я согласен с первым замечанием - да, начальный вид - это только окно журнала консоли сервиса, а диалог ввода данных можно рассматривать как другое представление. Hovewer, модель управляется алгоритмом, и я нахожу довольно сумасшедшим, чтобы разбить один алоризм на части, асинхронно вызываемые пользовательским интерфейсом - и в некоторых случаях это действительно невозможно. Кроме того, с точки зрения ремонтопригодности, гораздо лучше иметь алгоритм в одном методе. Поэтому вызов GUI должен быть синхронным. –

+0

Я точно понимаю, что вы имеете в виду. Я должен был использовать государственные машины в некоторых действительно раздражающих местах. Хотя я знаю, что вы не хотите туда ехать, у вас есть хороший шанс. Если нет, здорово, но вы можете подумать об этом - вероятно, вы закончите. Диалоговое окно часто подразумевает освобождение потока. Я не соглашусь с вашей точкой зрения, что это сумасшествие, хотя :) –

1

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