ViewModels w ViewModelLocator MVVM Light

Czy poprawne jest przechowywanie wszystkich moich ViewModels w simple? Na przykład mam trzy strony Strona główna, zdjęcia, katalogi (dlatego trzy ViewModels - > MainVM, PhotosVM, DirectoriesVM). Czy powinienem ustawić DataContext na każdej stronie, aby wyświetlić właściwość modelu w ViewModelLocator lub zagnieżdżać ViewModels jako właściwości w MainVM i powiązać każdą stronę DataContext do Main.PhotosVMProperty, Main.DirectoriesVMProperty i tak dalej? Czy ktoś mógłby mi wyjaśnić ideę i cel MKOl ?

Author: McGarnagle, 2013-01-03

2 answers

Najpierw zobaczmy, co robi ViewModelLocator i dlaczego go używamy:

ViewModelLocator jest zadeklarowany jako obiekt w naszej aplikacji.strona xaml i jest aplikacją singleton. Będziemy mieć jeden i tylko jeden z nich Dostępny dla aplikacji, gdy będzie działać.

ViewModelLocator jest źródłem wszystkich naszych ViewModels w świetle MVVM. Dla każdego modelu ViewModel będziemy mieli właściwość na ViewModelLocator, która pozwala nam uzyskać Model ViewModel dla widoku. Ten kod wygląda następująco to:

public class ViewModelLocator
{
    public MainPageViewModel MainPage
    {
        get { return new MainPageViewModel(); }
    }
}
To część mojej aplikacji.xaml:
<Application.Resources>
    <vm:ViewModelLocator
        x:Key="ViewModelLocator" />
</Application.Resources>

To jest kawałek z widoku.xaml

DataContext="{Binding MainPage, Source={StaticResource ViewModelLocator}}"
Jak na razie dobrze. Aby odpowiedzieć na pierwsze pytanie, czy musisz używać Ioc w MVVM Light? Nie. Nie ma potrzeby, ponieważ twój viewmodel zostanie przekazany do widoku w pełni zbudowanego i stworzonego przez ViewModelLocator. A teraz drugie pytanie: jaki jest cel MKOl?

IoC ma na celu umożliwienie wykonywania następujących czynności:

Z Mvvm Light robisz powyższe Tak:

public class ViewModelLocator
{
    public ViewModelLocator()
    {
        ServiceLocator.SetLocatorProvider(() => SimpleIoc.Default);

        if (ViewModelBase.IsInDesignModeStatic)
        {
            SimpleIoc.Default.Register<IDataService, Design.DesignDataService>();
        }
        else
        {
            SimpleIoc.Default.Register<IDataService, DataService>();         
        }

        SimpleIoc.Default.Register<MainViewModel>();
    }

    public MainViewModel Main
    {
        get { return SimpleIoc.Default.GetInstance<MainViewModel>(); }
    }
}

public class MainViewModel
{
    public ObservableCollection<Foo> Foos { get; set; }

    public MainViewModel(IDataService dataService)
    {
        _dataService=dataService;
        Foos=_dataService.GetFoos();
    }
}

Kiedy rozwiążę mój MainViewModel kiedy wywołam

SimpleIoc.Default.GetInstance<MainViewModel>()

To, co dzieje się wewnętrznie, To to, że SimpleIoc sprawdza, czy MainViewModel ma jakieś zależności (parametry w konstruktorze). Następnie próbuje rozwiązać te parametry, patrząc na interfejsy, które zostały z nim zarejestrowane. Robi to rekurencyjnie, więc gdyby DataService miał zależność, zostałby utworzony i przekazany do konstruktora DataService, gdy był instancja również.

Po co miałbym to wszystko robić?
  1. spraw, aby Twoje klasy były łatwo testowane jednostkowo
  2. spraw, aby twój interfejs kodu był sterowany. Oznacza to, że odwołujesz się do interfejsów, a nie do konkretnych klas.]}
  3. niech twój kod będzie luźno powiązany. Oznacza to, że ktoś może zmienić implementację interfejsu, A klasy, które go wykorzystują, nie dbają o to i nie muszą być ponownie kodowane.
  4. Rozwiąż zależności klas w zautomatyzowany sposób.
  5. W MVVM Light zobaczysz, że może określić, kiedy działa w trybie projektowania (ViewModelBase.IsInDesignModeStatic), co oznacza, że możesz tworzyć usługi czasu projektowania, aby dostarczyć dane modelu widoku, aby Widok w Visual Studio zawierał rzeczywiste dane.
 120
Author: Faster Solutions,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-04-27 13:34:05

MVVM Light ma wiele fajnych funkcji, ale wydaje mi się, że Lokalizator usług tworzy niechcianą zależność widoków od modeli widoków. Idealnie, chciałbym mieć ViewModelLocator w bibliotece A, modele widoku w Bibliotece B i widoki w Bibliotece C. Następnie Mogę mieszać i dopasowywać je w razie potrzeby dla przyszłych projektów. Jednak w projektowaniu MVVM Light, o ile widzę, widoki (biblioteka C) zawsze będą miały zależność od ViewModelLocator (to jest w porządku), ale ponieważ ViewModelLocator (Biblioteka A) zawsze będzie zależny od modeli widoku (Biblioteka B), wtedy widoki zawsze będą zależeć od modeli widoku (nie jest to w porządku, ponieważ Widok musi teraz zawierać wszystkie biblioteki modeli widoku, z którymi kiedykolwiek był używany we wszystkich produktach).

Uważam, że Prism obejdzie ten problem używając w jakiś sposób klawiszy string. Coś przeoczyłem?

Oops! Myślę, że właśnie odpowiedziałem na własne pytanie. Rozwiązaniem jest uczynienie biblioteki a, ServiceLocator, specyficzny dla danego rozwiązania(produktu). Następnie zawiera odniesienie do modeli widoków tylko dla tego rozwiązania. Następnie widoki zależą od tego ServiceLocator, który z kolei zależy od wszystkich modeli widoków dla tego produktu. Efektem końcowym jest to, że widoki zależą tylko od modeli widoków, z którymi będą używane dla tego produktu. Nie ma problemu z tym, że powielamy ServiceLocator dla każdego rozwiązania, ponieważ ten moduł zawiera tylko kod, który jest specyficzny dla rozwiązania. Komponenty ServiceLocator, takie jak Klasa SimpleIoc, są oczywiście wspólne dla wszystkich rozwiązań, ale zostały one uwzględnione w klasach wielokrotnego użytku, które wywołujemy w ServiceLocator.

Podsumowując, problem, który próbuję rozwiązać, polega na założeniu, że rozwiązanie ma 6 modeli widoku, z których cztery są blisko spokrewnione, a dwa są blisko spokrewnione. Dlatego tworzymy dwa zespoły, z których każdy zawiera ściśle powiązane modele widoków. Załóżmy, że zaprojektujemy produkt, który wykorzystuje jeden zestaw modeli widoków, a rozwiązanie jest przeznaczone do uruchamiania systemu Windows 8. Teraz widoki są różne i chcemy ponownie użyć tylko jednego zestawu (zestawu) modeli widoków. Więc po prostu tworzymy nowy zespół ServiceLocator, który wskazuje na ten zespół modeli widoku, a także wszelkie inne, których potrzebujemy. Nasze nowe widoki Windows 8 zależą teraz Od tego nowego zespołu ServiceLocator i tylko Modeli widoków, które są używane w naszym nowym produkcie (rozwiązaniu).

 1
Author: Richard,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-06-20 02:31:22