2009-11-11 17 views
26

Sto studiando il modello di progettazione MVVM di WPF. Ma sono incerto su dove inserire il codice Data Acess?MVVM dove inserire Data Access Layer?

In alcuni esempi che ho guardato, l'accesso ai dati viene eseguita direttamente nel ViewModel. Sembra strano inserire qualcosa come linq in sql nel ViewModel? Altri esempi hanno un progetto separato per l'accesso ai dati, questo sembra più simile?

ci sia questo un approccio generale? Mi sento come se mi mancasse qualcosa qui!

Grazie

+2

A volte il codice di esempio viene scritto per illustrare il punto. Il codice di produzione dovrebbe essere scritto in modo che sia gestibile e compreso. – Min

risposta

11

vorrei aggiungere un altro strato, in sostanza, ciò che si desidera è una fabbrica di dati. Si desidera creare un set di classi che CRUD si aggiungerà al database e restituire oggetti POCO puliti al ViewModel.

Un buon esempio a guardare sarebbe il libro Nerd Dinner. Copre MVC non MVVM ma i modelli sono molto simili e il modo in cui accedono ai dati in quella soluzione sarebbe un buon punto di partenza.

Spero che questo aiuti.

+2

Grazie. Mi piace il modo in cui Nerd Dinner utilizza il pattern di repository (come suggerito anche da Kristoffer). In termini di struttura dei file, penso che separerò la classe di repository e i mappatori associati in una directory di accesso ai dati. Sembra ancora che si tratti di una vasta area che non viene menzionata in MVVM. Grazie ancora. –

+0

L'esempio NerdDinner è davvero un buon esempio del modello di repository. Esse tuttavia espongono il modello di dominio nelle viste (ad esempio non utilizzano MVVM), che è considerato una cattiva pratica. – Kristoffer

+0

@ Lukasz, in una cena da nerd chiamano direttamente i metodi da linq a sql. Va bene? I modelli non saranno le classi generate da linqtosql? –

5

MVVM sta per Modello, View, e ViewModel. Il pezzo che ti manca è il Modello, che è il luogo in cui risiede il tuo codice di accesso ai dati.

Il ViewModel prende il modello e lo presenta alla vista per la visualizzazione, così tipicamente si dovrebbe avere qualcosa di simile:

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; } 
    } 
} 

Il PersonView sarebbe quindi associare alle proprietà del PersonViewModel piuttosto che direttamente al modello stesso. In molti casi potresti già disporre di un livello di accesso ai dati che non sa nulla di MVVM (e non dovrebbe farlo), ma puoi ancora creare ViewModels per presentarlo alla vista.

+1

Scegli questo. –

+0

Dai un'occhiata a http://jonas.follesoe.no/YouCardRevisitedImplementingTheViewModelPattern.aspx –

+0

Vale la pena notare che ciò sarebbe difficile da implementare in scenari multi-database, in quanto sarebbe necessario passare il contesto db al modello. Questo è il motivo principale per cui siamo andati con il modello di repository ... avendo il CRUD in una libreria di classi separata. Il tuo chilometraggio varierà. –

10

L'accesso ai dati deve essere non essere nel modello di vista, in quanto questa dovrebbe essere una rappresentazione specifica (eventualmente semplificata) del modello di dominio.

Utilizzare un mapper di qualche tipo per mappare il modello di vista (la VM in MVVM) al modello (il primo M). Nuovi oggetti nel tuo modello possono essere creati usando il modello di fabbrica. Una volta creati, è possibile memorizzarli in un database utilizzando il modello di repository. I repository rappresenterebbero quindi il livello di accesso ai dati. Nel tuo repository puoi usare un mappatore O/R come NHibernate o Entity Framework.

EDIT:
vedo che GraemeF suggerisce di mettere il codice di accesso ai dati nel modello. Questo è un NON un buon approccio , in quanto questo si dovrebbe forzare l'aggiornamento del modello di dominio se si dovesse passare da esempio Da SQL Server a Oracle o file XML. Gli oggetti dominio non devono preoccuparsi di come sono persistenti. Il modello di repository isola il dominio dalla sua persistenza.

+1

Buon punto; ovviamente puoi prenderlo molto oltre. Il mio punto è che il codice di accesso ai dati è nascosto dietro quell'interfaccia e non risiede nel ViewModel. – GraemeF

1

tuo ViewModel dovrebbe essere uno strato sottile che solo servizi la vista. La mia regola generale: se ha a che fare con la presentazione dell'interfaccia utente, allora appartiene al ViewModel, altrimenti dovrebbe essere nel modello.

40

Ecco come sto organizzando il mio MVVM w/progetti LINQ:

Modello - penso al modello come lo stato del sistema. Fornisce un'interfaccia per i dati e tiene traccia dello stato del sistema. Il Modello non conosce ViewModel o View - fornisce solo un'interfaccia pubblica ai suoi dati e vari eventi per consentire ai consumatori (solitamente ViewModels) di sapere quando lo stato è cambiato.

ViewModel - Il ViewModel è incaricato di organizzare o strutturare tutti i dati necessari per la visualizzazione, tenere traccia dello stato della vista (ad esempio la riga attualmente selezionata di una griglia di dati), e rispondendo alle azioni sulla vista (come i pulsanti). Sa cosa la vista ha bisogno di, ma in realtà non conosce la vista.

View - The View è l'aspetto reale dell'interfaccia utente. Contiene tutti i controlli incorporati e personalizzati, come sono organizzati e come sono stilizzati. Conosce il ViewModel, ma solo allo scopo di legarsi alle sue proprietà.

Gateway - Questa è la parte che risponde direttamente alla tua domanda. Il gateway (che è fondamentalmente il mio modo di dire "DataAccessLayer") è il suo livello separato. Contiene tutto il codice (comprese le query LINQ) in CRUD o seleziona, inserisce, aggiorna ed elimina i dati da/verso l'origine dati (database, file XML, ecc.). Fornisce inoltre un'interfaccia pubblica al modello, consentendo al modello di concentrarsi sulla gestione dello stato del sistema senza doversi preoccupare dei dettagli (ad es. Le query) necessari per aggiornare l'origine dati.

Classi DataAccess - In C#, sono classi molto semplici che modellano gli oggetti dati elementali. Quando si seleziona qualcosa utilizzando una query LINQ, di solito si crea uno IEnumerable<T> o List<T> dove T è uno degli oggetti dati. Un esempio di un oggetto di dati sarebbe:

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

Il grande vantaggio di un progetto come questo è che separa veramente le vostre preoccupazioni. Tutto ha un lavoro specializzato, ed è (solitamente) abbastanza facile sapere che tipo di cose vanno dove.

Lo svantaggio è che potrebbe essere eccessivo per piccoli progetti. Finisci per creare una grande infrastruttura per le interfacce pubbliche che sostanzialmente passano un singolo desiderio attraverso diversi livelli. Così, si potrebbe finire con uno scenario come questo: [l'utente fa clic su Invia, ViewModel dice Modello a AddNewPerson, Modello dice Gateway a InsertPerson] invece di uno scenario come questo [l'utente fa clic su Invia, ViewModel aggiunge direttamente un nuovo record al database].

Spero che questo aiuti.

+7

potresti per cortesia fornire un breve esempio della tua interpretazione di mvvm perché ho sempre raggiunto un punto morto se cerchi delle buone soluzioni DAL – WiiMaxx

2

Il WPF Application Framework (WAF) contiene un'applicazione di esempio che mostra come il pattern Model-View-ViewModel (MVVM) potrebbe essere usato in combinazione con Entity Framework.

Problemi correlati