2010-04-27 9 views
12

Sto utilizzando l'architettura S # arp e non riesco a ricordare dove l'ho letto, ma dicono che ViewModels deve essere archiviato sul livello di servizio e le tue visualizzazioni devono inviare il viewmodel al servizio per l'elaborazione.Quale livello deve costruire un modello di vista?

La mia domanda è questa. Quale strato dovrebbe costruire il ViewModel? Dovrebbe essere al livello di servizio e il controller lo richiede? O dovrebbe il controllore costruirlo da solo? C'è anche una domanda sull'aggiornamento del modello di vista, come se contenga collezioni, e lo stato del modello non è valido, dovrai anche ripopillare qualsiasi lista.

Qualche suggerimento?

Molte grazie

Matt

risposta

8

creo vista modelli all'interno controllori. I controllori accettano le entità di dominio (recuperate dal database dai raccoglitori di modelli), possibilmente all'interno di altri modelli di vista, contattano i repository per ulteriori dati, creano un nuovo modello di vista e lo passano alla vista appropriata (o al reindirizzamento). Pertanto, la responsabilità del controllore è quella di preparare view/viewmodel in base ai dati del dominio di input (e gestire gli errori, ovviamente).

È possibile cercare here come alternativa alla creazione di modelli di visualizzazione nel controller. Questa tecnica sposta la creazione del modello di vista all'esterno delle azioni, in modo che non solo le azioni del controller accettano oggetti di dominio puri, ma restituiscono anche oggetti di dominio puri. Non direi che sia appropriato in tutti i casi, ma è molto interessante da imparare.

La tecnica di cui sopra, correlata a AutoMapper, ha sollevato anche domande simili a "devo passare viewmodels al livello di servizio". No, non lo fai. Se è necessario passare l'oggetto complesso al livello di servizio o dominio, si definisce questo oggetto nel livello servizio/dominio appropriato e lo si utilizza per passare i dati a tali livelli. Questo oggetto può quindi essere facilmente mappato su/dai modelli di visualizzazione (ad esempio, utilizzando AutoMapper). Ma i tuoi livelli inferiori (servizio/dominio) non dovrebbero essere accoppiati ai livelli superiori (vista/controllori). Non in questo caso, non in altri. Mai gli strati di basso livello dovrebbero dipendere da qualcosa sopra definito.

+0

Questo è praticamente quello che sto facendo ora, ma devo fare qualcosa in modo errato, in quanto mi sembra di avere molte logiche condizionate quando mi occupo del modello di vista sul dominio. Forse ho bisogno di rompere la mia vista in pezzi più piccoli. –

+0

Attualmente ho una vista di modifica che addapts in base allo stato dell'entità. Farei meglio a creare più viste per i diversi stati? –

+0

Senza vedere la tua vista di modifica e modelli, è difficile rispondere. – queen3

3

Questi articoli potrebbero essere interessanti per voi:

DDD : Command Query Separation as an Architectural Concept

Better Application Services and CQS using S#arp Architecture

C'è un'applicazione di esempio associata al 2 ° articolo che ha i modelli vista e forma in un livello di servizi, invece di il controller.

+1

Questa è la risposta corretta. Tuttavia, di solito inizio con ViewModel nel controller e lo trasferisco al livello di servizio man mano che il controller si evolve. –

+0

I collegamenti non sono disponibili, forse http://sharp-architecture.readthedocs.io/en/latest/additional-resources/additional-information.html sarà di aiuto? – kristianp

0

anche guardare Who Can Help Me - è fantastico. questo framework è basato su S # arp Architecture. tra le altre cose, ha molte indicazioni per Visualizza/Form/Modifica viewModels.

11

Secondo l'approccio tradizionale o teoria, ViewModel dovrebbe essere parte del livello di interfaccia utente. Almeno il nome dice così.

Ma quando si inizia a implementarlo autonomamente con Entity Framework, MVC, Repository ecc., Si realizza qualcos'altro.

Qualcuno deve mappare i modelli di entità con ViewModels (DTO menzionato alla fine). Dovrebbe essere fatto in A) il livello dell'interfaccia utente (dal controller), o in B) il livello di servizio?

Vado con l'opzione B. L'opzione A è un no-no a causa del semplice fatto che diversi modelli di entità si combinano insieme per formare un ViewModel.Non possiamo passare i dati non necessari al livello dell'interfaccia utente, mentre nell'opzione B, il servizio può giocare con i dati e passare solo il necessario/minimo al livello dell'interfaccia utente dopo la mappatura (al ViewModel).

Ma, supponiamo di andare con l'opzione A, mettiamo ViewModel nel livello dell'interfaccia utente (e modello di entità nel livello di servizio).

Se il livello Servizio deve essere associato a ViewModel, il livello Servizio deve accedere a ViewModel nel livello dell'interfaccia utente. Quale biblioteca/progetto? Viewmodel dovrebbe essere in un progetto separato nel livello dell'interfaccia utente e questo progetto deve essere referenziato dal livello di servizio. Se ViewModel non si trova in un progetto separato, allora c'è un riferimento circolare, quindi non andare. Sembra imbarazzante che il livello di servizio acceda al livello dell'interfaccia utente, ma siamo comunque in grado di gestirlo.

Ma cosa succede se c'è un'altra app per l'interfaccia utente che utilizza questo servizio? Cosa succede se c'è un'app mobile? Quanto può essere diverso il ViewModel? Il servizio deve accedere allo stesso progetto di modello di vista? o tutti i progetti UI saranno in competizione?

Dopo queste considerazioni la mia risposta sarebbe quella di mettere il progetto Viewmodel in Service Layer. Comunque, ogni livello dell'interfaccia utente deve accedere al livello di servizio! E potrebbero esserci molti ViewModels simili che tutti potrebbero usare (quindi la mappatura diventa più facile per il livello di servizio). I mapping sono fatti attraverso linq in questi giorni, che è un altro vantaggio.

Infine c'è questa discussione sul DTO. E anche sull'annotazione dei dati in ViewModels. ViewModels con annotazioni di dati non possono risiedere nel livello di servizio. Quindi DTO sarà una copia esatta di ViewModel con una mappatura uno a uno tra i due (diciamo con AutoMapper). Ancora una volta DTO ha ancora la logica necessaria per l'interfaccia utente (o più applicazioni) e risiede in Service Layer. E lo strato UI di ViewModel è solo per copiare i dati dal DTO, con qualche "comportamento" (ad esempio: attributo) aggiunto ad esso.

Anche se non direttamente correlato alla domanda. 'ViewModel Façade' (viewmodel all'interno di un'altra viewmodel) & 'command' menzionato in questo deve guardare channel 9 link vale la pena esplorare (@ 11: 48 inizia)