2009-05-19 6 views
6

Sto scrivendo un'app che è in ascolto su una connessione di rete, e quando alcuni dati arrivano, risponde e, a seconda dei dati in arrivo, potrebbe essere necessario chiedere all'utente (mostra la finestra di dialogo) prima di rispondere.Come ottenere in modo pulito l'input dell'utente dal centro del metodo del modello nell'architettura Model-View-Viewmodel?

Non so come farlo in modo pulito nell'architettura MV-VM: gli eventi e il binding alle raccolte osservabili sono carini se ho bisogno di aggiornare solo la GUI in base ai dati in arrivo, ma cosa succede se ho effettivamente bisogno di una anwer da utente prima di rispondere?

E per peggiorare le cose, voglio farlo in modo sincrono, perché voglio che l'algoritmo di risposta sia in un posto, non suddiviso in più callback con responsabilità "chi chiama-chi" non chiare.

Semplicemente, qualcosa come

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

ma non voglio chiamare vista o viewmodel dal modello, come il modello ha bisogno di essere riutilizzabili e verificabile - io non voglio popping finestre di dialogo in ogni prova, e sarebbe una violazione di MVVM! Non ci sono eventi (sono solo a senso unico, per quanto ne so, e non hanno alcun canale a ritroso per ottenere risposta all'origine degli eventi) o al database, in quanto sarebbe asincrono.

È fattibile? Questa è una domanda che ho posto a diversi propagatori di sviluppo basati su test, e fino ad ora non ho ottenuto una risposta praticamente utilizzabile. Tuttavia, la necessità di alcuni input aggiuntivi nel mezzo dell'elaborazione è abbastanza comune.

Grazie!

EDIT: questa è la logica dell'applicazione, quindi appartiene chiaramente al modello, e anche se in questo caso non lo fosse, mi piacerebbe conoscere la soluzione per i casi in cui ho davvero bisogno di input dell'utente nel mezzo del business routine logica nel modello.

risposta

3

Questo è uno di quei problemi che MVVM non risolve autonomamente. Una soluzione potrebbe essere quella di utilizzare un servizio per interrogare l'utente e quindi utilizzare ViewModel per quel servizio.

Nel mio progetto stiamo usando PRISM che oltre a fornire un framework di servizi fornisce anche altri strumenti per facilitare lo sviluppo di GUI.

Here's una descrizione di come i servizi funzionano in PRISM.

Quindi, in particolare nel tuo caso creerei una sorta di IOC, registrerò un servizio di query con esso, quindi nel pass ViewModel nello IOC e quindi utilizzerò lo IOC per ottenere il servizio query e lo useremo per interrogare l'utente . Più lavoro? Sicuro.Ma significa che è possibile sostituire il servizio query con un'altra implementazione per il test semplicemente sostituendolo nel COI.

MVVM + Servizi = Potenza massima!

+0

+1 per averlo spiegato molto meglio di quanto ho fatto io. –

+0

Grazie, sembra una soluzione pulita, leggerò i collegamenti (grazie per loro!) –

0

In realtà, non TUTTI appartengono alla logica dell'applicazione.

Sembra che tu abbia 2 diversi "punti di vista". C'è quello iniziale (i dati arrivano sulla rete), e un secondo (finestra di dialogo di conferma).

Il modello deve determinare che deve essere visualizzata una nuova vista, segnalare la vista per visualizzarla, quindi rispondere successivamente all'input da quella vista.

Non provare a fare tutto in un solo passaggio.

+0

Sono d'accordo con la prima osservazione: sì, la vista iniziale è solo la finestra del registro della console del servizio e la finestra di dialogo per l'immissione dei dati può essere vista come un'altra vista. Hovewer, il modello è guidato da algoritmi e trovo piuttosto folle dover suddividere un alorithm in parti chiamate in modo asincrono dall'interfaccia utente - e in alcuni casi, non è realmente possibile. Inoltre, dal punto di vista della gestibilità, è molto meglio avere un algoritmo in un metodo. Pertanto, la chiamata alla GUI deve essere sincrona. –

+0

Capisco esattamente cosa intendi. Ho dovuto usare le macchine di stato in alcuni posti davvero irritanti. Anche se so che non vuoi andare lì, ci sono buone probabilità che tu debba farlo. In caso contrario, ottimo, ma potresti volerlo ricomporre - è probabilmente quello che finirai per fare. Una finestra di dialogo implica spesso il rilascio del thread. Non sono d'accordo con il punto che è pazzesco però :) –

1

Non so se questa idea è in stretta conformità con i principi di MVVM, ma ... vorrei incapsulare la funzionalità di dialogo come un servizio (referenziato tramite un'interfaccia). L'implementazione del servizio sarebbe nel livello dell'interfaccia utente, ma a scopo di test si sarebbe semplicemente "deriso" l'interfaccia.