Message Boxes w MVVM

Wzorzec Model-View-ViewModel jest najczęściej wykorzystywany przez programistów WPF. Związane jest to z mechanizmem wiązań, który znacząca ułatwia wdrożenie MVVM do projektu. ViewModel stanowi wyeksponowany model przeznaczony do bindingu, z kolei widok to zwykły, pasywny plik XAML. Ważną cechą ViewModel jest brak powiązań z interfejsem użytkownika. Najlepiej aby projekt zawierający ViewModel nie posiadał żadnych referencji do bibliotek warstwy prezentacji.

Częstym zadawanym pytaniem jest: Jak wywoływać standardowe okna komunikatów  (MessageBox)? Aby poprawnie zaimplementować VM, nie powinno się wywoływać komunikatów bezpośrednio VM. Umieszczenie wywołań w Code-Behind również nie jest dobrym podejściem (często messagebox zależą od logiki biznesowej oraz nie powinniśmy umieszczać kodu w code-behind).

Najlepszym rozwiązaniem jest stworzenie usługi odpowiedzialnej za wyświetlanie komunikatów a następnie załadowanie jej z kontenera. Interfejs reprezentujący takową usługę mógłby wyglądać następująco:

interface IMessageBoxService
{
    Result Show(string message);
}

Z kolei przykładowe implementacje:

class RealMessageBoxService: IMessageBoxService
{
    public Result Show(string message)
    {
        MessageBox.Show(message);
        return Result.OK // w tym miejscu powinnismy zmapowac wynik zwrocony przez MessageBox do wlasnego enum.
    }
}
class MockBoxService: IMessageBoxService
{
    public Result Show(string message)
    {
        return Result.OK;
    }
}

Następnie w ViewModel powinniśmy skorzystać z kontenera (IoC, np. UnityContainer) aby uzyskać instancję usługi:

IMessageBoxService service = container.Resolve<IMessageBoxService>();

Dzięki wstrzyknięciu zależności, możemy w łatwy sposób przełączać się między prawdziwą implementacją wyświetlającą komunikat a zwykłym stubem. Podsumowując z przedstawionego w tym poście podejścia zyskujemy:

  1. Niezależność od bibliotek warstwy prezentacji (System.Windows itp.)
  2. TESTOWALNOŚĆ – wyświetlając komunikaty bezpośrednio w VM pozbawieni jesteśmy możliwości skorzystania z testów jednostkowych (testy jednostkowe wymagające interakcji użytkownika?- zaprzeczenie głównym zasadom). W przypadku usług, możemy wstrzyknąć zwykły MOCK object i przetestować kod – nawet w przypadku skomplikowanych worflow’ów w których logika biznesowa zależy od interakcji użytkownika.
  3. Jedno miejsce w kodzie w którym można umieszczać metody odpowiedzialne za wyświetlanie najpopularniejszych okien dialogowych. W końcu można stworzyć dodatkowe metody typu ShowWelcomeText itp. w klasie implementującej usługę.

One thought on “Message Boxes w MVVM”

Leave a Reply

Your email address will not be published.