2009-11-11 12 views
26

Badam wzorzec projektowy MVVM WPF. Ale nie jestem pewien, gdzie umieścić kod Data Acess?MVVM gdzie umieścić warstwę dostępu do danych?

W niektórych przykładach, na które patrzyłem, dostęp do danych odbywa się bezpośrednio w ViewModelu. Wydaje się dziwne umieścić coś podobnego do linq do sql w ViewModel? Inne przykłady mają osobny projekt dostępu do danych, wydaje się bardziej podobny do niego?

Czy jest to podejście ogólne? Czuję, że tu coś pomijam!

Dzięki

+2

Czasem przykładowy kod jest napisany w celu zilustrowania punktu. Kod produkcji powinien być napisany tak, aby można go było utrzymywać i rozumieć. – Min

Odpowiedz

11

Dodam kolejną warstwę, w zasadzie to, co chcesz to fabryka danych. Chcesz utworzyć zestaw klas, który spowoduje, że CRUD zostanie dodany do bazy danych i zwróci czyste obiekty POCO do ViewModel.

Dobrym przykładem jest książka Nerd Dinner. Obejmuje ona MVC, a nie MVVM, ale wzorce są bardzo podobne, a sposób, w jaki uzyskują dostęp do danych w tym rozwiązaniu, byłby dobrym punktem wyjścia.

Mam nadzieję, że to pomoże.

+2

Dzięki. Podoba mi się sposób, w jaki Nerd Dinner używa wzorca repozytorium (jak również sugeruje Kristoffer). Jeśli chodzi o strukturę plików, myślę, że oddzielę klasę Repository i skojarzone mapowania do katalogu Data Access. Nadal wydaje się, że jest to duży obszar, który w dużej mierze nie jest wspomniany w MVVM. Dzięki jeszcze raz. –

+0

Przykład NerdDinnera jest rzeczywiście dobrym przykładem wzorca repozytorium. Jednakże eksponują model domeny w widokach (tzn. Nie używają MVVM), co jest uważane za złą praktykę. – Kristoffer

+0

@ Lukasz, w nerd obiad nazywają bezpośrednio linq do sql metod. Czy to w porządku? Modele woul być klasy generowane frol linqtosql? –

5

MVVM oznacza Modelu, View i ViewModel. Brakujący element to model, w którym znajduje się twój kod dostępu do danych.

ViewModel trwa modelu i przedstawia je do widoku na ekranie, więc zazwyczaj trzeba coś takiego:

class PersonModel : IPerson 
{ 
    // data access stuff goes in here 
    public string Name { get; set; } 
} 

class PersonViewModel 
{ 
    IPerson _person; 

    public PersonViewModel(IPerson person) 
    { 
     _person = person; 
    } 

    public Name 
    { 
     get { return _person.Name; } 
     set { _person.Name = value; } 
    } 
} 

PersonView będzie wtedy wiązania właściwości PersonViewModel zamiast bezpośrednio do sam model. W wielu przypadkach możesz już mieć warstwę dostępu do danych, która nic nie wie o MVVM (i nie powinna), ale nadal możesz budować ViewModels, aby zaprezentować ją w widoku.

+1

Wybierz ten. –

+0

Sprawdź http://jonas.follesoe.no/YouCardRevisitedImplementingTheViewModelPattern.aspx –

+0

Warto zauważyć, że byłoby to trudne do wdrożenia w scenariuszach z wieloma bazami danych, ponieważ trzeba przekazać kontekst db do modelu. Jest to główny powód, dla którego poszliśmy z modelem repozytorium ... mając CRUD w oddzielnej bibliotece klas. Twój przebieg będzie się różnić. –

10

Dostęp do danych powinien być nie być w modelu widoku, ponieważ ma to być specyficzna dla widoku (prawdopodobnie uproszczona) reprezentacja modelu domeny.

Użyj jakiegoś programu odwzorowującego, aby zmapować model widoku (maszyna wirtualna w MVVM) do swojego modelu (pierwsze M). Nowe obiekty w modelu można tworzyć przy użyciu wzoru fabrycznego. Po utworzeniu można je przechowywać w bazie danych za pomocą wzorca repozytorium. Repozytoria będą reprezentowały twoją warstwę dostępu do danych. W twoim repozytorium możesz użyć programu odwzorowującego O/R, takiego jak NHibernate lub Entity Framework.

EDIT:
widzę, że GraemeF proponuje wprowadzenie kodu dostępu do danych w modelu. Jest to dobre podejście, ponieważ zmusiłoby to do zaktualizowania modelu domeny, gdybyś miał przejść z np. SQL Server do plików Oracle lub XML. Obiekty domeny nie powinny martwić się o to, jak są trwałe. Wzór repozytorium izoluje domenę od jej trwałości.

+1

Dobra rada; oczywiście możesz wziąć to o wiele dalej. Chodzi mi o to, że kod dostępu do danych jest ukryty za tym interfejsem i nie jest dostępny w ViewModelu. – GraemeF

1

Twój ViewModel powinien być cienką warstwą, która obsługuje widok. Moja zasada: jeśli ma to związek z prezentacją interfejsu użytkownika, to należy do ViewModel, w przeciwnym razie powinien być w Modelu.

40

Oto jak ja organizuje mój MVVM w/projektów LINQ:

model - myślę o model, stan systemu. Zapewnia interfejs do danych i śledzi status systemu. Model nie wie o ViewModelu ani widoku - zapewnia jedynie publiczny interfejs do danych i różnych zdarzeń, aby konsumenci (zwykle ViewModels) wiedzieli, kiedy stan się zmienił.

ViewModel - ViewModel jest odpowiedzialny za organizację i struktury wszystkich danych wymaganych przez View, śledzenie statusu widzenia (jak aktualnie zaznaczonego wiersza siatki danych), oraz reagowanie na działania na widoku (np. naciśnięcia przycisków). Wie, jaki musi być widok, ale w rzeczywistości nie wie o widoku.

Wyświetl - Widok jest rzeczywistym wyglądem interfejsu użytkownika. Zawiera wszystkie wbudowane i niestandardowe elementy sterujące, sposób ich rozmieszczenia i styl. Wie o modelu ViewModel, ale tylko w celu powiązania z jego właściwościami.

Gateway - To jest część, która bezpośrednio odpowiada na twoje pytanie. Brama (która jest w zasadzie moim sposobem powiedzenia "DataAccessLayer") jest osobną warstwą. Zawiera cały kod (w tym zapytania LINQ) do CRUD lub wybierz, wstaw, aktualizuj i usuń dane z/do twojego źródła danych (bazy danych, pliku XML itp.). Zapewnia także publiczny interfejs do Modelu, umożliwiając modelowi skupienie się na utrzymywaniu stanu systemu bez konieczności zajmowania się szczegółami (tj. Zapytaniami) potrzebnymi do aktualizacji źródła danych.

DataAccess Classes - W języku C# są to bardzo proste klasy, które modelują twoje elementarne obiekty danych. Gdy wybierzesz coś za pomocą zapytania LINQ, zwykle utworzysz IEnumerable<T> lub List<T>, gdzie T jest jednym z twoich obiektów danych. Przykład obiektu danych to:

public class Person 
{ 
    public string Name { get; set; } 
    public int Age { get; set; } 
} 

Wielką zaletą takiego projektu jest to, że naprawdę oddziela twoje obawy. Wszystko ma wyspecjalizowaną pracę i (zazwyczaj) dość łatwo jest wiedzieć, o co chodzi.

Wadą jest to, że może to być przesada w przypadku małych projektów. W efekcie powstaje wiele infrastruktury dla publicznych interfejsów, które w zasadzie przekazują jedno życzenie przez kilka warstw. Tak więc możesz skończyć scenariuszem podobnym do tego: [użytkownik klika Submit, ViewModel mówi Modelowi do AddNewPerson, Model mówi Gateway to InsertPerson] zamiast takiego scenariusza [użytkownik klika Submit, ViewModel dodaje nowy rekord bezpośrednio do bazy danych].

Nadzieję, że pomaga.

+7

czy mógłbyś podać krótki przykład twojej interpretacji mvvm, ponieważ zawsze szukałem ślepych zaułków, szukając dobrych rozwiązań DAL – WiiMaxx

2

The WPF Application Framework (WAF) zawiera przykładową aplikację, która pokazuje, jak Model-View-ViewModel (MVVM) wzór może być stosowany w połączeniu z Entity Framework.

Powiązane problemy