Event Aggregators sono un bel modo per risolvere questo tipo di problema. Fondamentalmente c'è una classe centralizzata (per amor di semplicità diciamo che è un Singleton e affrontare la possibile ira dei ragazzi anti-singleton) che è responsabile del trasferimento di eventi da un oggetto all'altro. Con i vostri nomi di classe l'utilizzo può apparire come:
public class MainViewModel
{
public MainViewModel()
{
WordAddedEvent event = EventAggregator.Instance.GetEvent<WordAddedEvent>();
event.Subscribe(WordAdded);
}
protected virtual void WordAdded(object sender WordAddedEventArgs e)
{
// handle event
}
}
public class AddWordViewModel
{
//From the command
public void ExecuteAddWord(string word)
{
WordAddedEvent event = EventAggregator.Instance.GetEvent<WordAddedEvent>();
event.Publish(this, new WordAddedEventArgs(word));
}
}
Il vantaggio di questo modello è che si può facilmente estendere l'applicazione per avere più modi di parole che creano e molteplici ViewModels che sono interessati a parole che sono state aggiunte e non vi è alcun accoppiamento tra i due in modo da poterli aggiungere e rimuovere come necessario.
Se si vuole evitare il Singleton (e per scopi di test Vorrei suggerire di fare) allora può valere la pena guardare in iniezione di dipendenza, anche se questo è davvero tutto un altro problema.
Ok, pensiero finale. Vedo dalla rilettura della tua domanda che hai già una sorta di classe di servizio di Word che gestisce il recupero e l'archiviazione degli oggetti di Word. Non c'è motivo per cui il servizio non possa essere responsabile dell'innalzamento dell'evento quando viene aggiunta la nuova parola poiché entrambi i ViewModel sono già accoppiati ad esso. Anche se mi piacerebbe ancora suggerire l'EventAggregator è più flessibile e una soluzione migliore, ma YAGNI possono applicare qui
public class WordService
{
public event EventHandler<WordAddedEventArgs> WordAdded;
public List<string> GetAllWords()
{
//return words
}
public void SaveWord(string word)
{
//Save word
if (WordAdded != null) WordAdded(this, new WordAddedEventArgs(word));
//Note that this way you lose the reference to where the word really came from
//probably doesn't matter, but might
}
}
public class MainViewModel
{
public MainViewModel()
{
//Add eventhandler to the services WordAdded event
}
}
Che cosa si vuole evitare di fare anche se sta introducendo l'accoppiamento tra ViewModels che si creerà chiamando un comando su un ViewModel con l'altro, questo limiterà severamente le opzioni per espandere l'applicazione (e se un secondo ViewModel fosse interessato a nuove parole, è ora anche l'AddWordViewModel a dirlo?)
fonte
2009-04-28 17:42:49
Grazie per la descrizione molto dettagliata risposta. Dovrò scavare dentro :) Un sacco di divertimento in arrivo :) –
Sono andato al massimo OO con un enorme oggetto grafico per la mia implementazione MVVM.2 anni su tutta la linea e fare cambiamenti strutturali è piuttosto difficile. Vorrei essere andato per il modello aggregatore/mediatore in quanto la flessibilità è enorme. ATTENZIONE: perdite di memoria. Assicurati che il tuo aggregatore utilizzi riferimenti deboli. – Gusdor