Event Aggregators to całkiem niezły sposób na rozwiązanie tego typu problemów. Zasadniczo istnieje scentralizowana klasa (dla uproszczenia, powiedzmy, że to Singleton i staw czoła możliwemu gniewowi facetów anty-singleton), która jest odpowiedzialna za przenoszenie zdarzeń z jednego obiektu do drugiego. Ze swoimi nazwami klas użycie może wyglądać następująco:
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));
}
}
Zaletą tego układu jest to, że można bardzo łatwo rozszerzyć swoją aplikację mieć wiele sposobów tworzenia słów i wielu ViewModels, które są zainteresowane w słowach, które zostały dodane i nie ma połączenia między nimi, więc możesz je dodawać i usuwać, jak potrzebujesz.
Jeśli chcesz uniknąć pojedyncza (i dla celów testowych I sugerowałaby to zrobić), to może warto patrząc do wstrzykiwania zależności, mimo że tak naprawdę to zupełnie inna kwestia.
Okay, ostatnia myśl. Widzę po ponownym przeczytaniu twojego pytania, że masz już jakąś klasę Word Service, która obsługuje pobieranie i przechowywanie obiektów Word. Nie ma powodu, że usługa nie może być odpowiedzialna za podniesienie zdarzenia po dodaniu nowego słowa, ponieważ oba modele ViewModels są już z nim powiązane. Chociaż ja nadal sugerują EventAggregator jest bardziej elastyczny i lepszym rozwiązaniem, ale YAGNI mogą ubiegać się o
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
}
}
Co chcesz uniknąć robi choć wprowadza sprzężenie pomiędzy ViewModels że będziesz tworzyć poprzez wywołanie polecenia na jednym ViewModelu z innym, to poważnie ograniczy twoje możliwości rozszerzenia aplikacji (co jeśli drugi ViewModel zainteresował się nowymi słowami, czy to teraz AddWordViewModel ma obowiązek także o tym powiedzieć?)
Dziękuję za bardzo szczegółowy odpowiedź. Będę musiał się w to zagłapać :) Dużo zabawy nadchodzi :) –
Poszedłem na pełne OO z ogromnym wykresem obiektów dla mojej implementacji MVVM.2 lata później i dokonanie zmian strukturalnych jest dość trudne. Żałuję, że nie poszedłem do wzorca agregator/mediator, ponieważ elastyczność jest olbrzymia. UWAGA: Wycieki pamięci. Upewnij się, że agregator używa słabych odniesień. – Gusdor