2009-11-11 23 views
26

Estoy investigando el patrón de diseño MVVM de WPF. Pero no estoy seguro de dónde poner el código de acceso a datos?MVVM dónde colocar la capa de acceso a datos?

En algunos ejemplos que he examinado, el acceso a los datos se realiza directamente en ViewModel. Parece extraño poner algo como linq en sql en el ViewModel? Otros ejemplos tienen un proyecto separado para Acceso a datos, esto parece más parecido?

¿Es esto un enfoque general? ¡Siento que me falta algo aquí!

Gracias

+2

A veces, el código de muestra se escribe para ilustrar el punto. El código de producción debe escribirse para que pueda mantenerse y entenderse. – Min

Respuesta

11

me gustaría añadir otra capa, esencialmente, lo que quiere es una fábrica de datos. Desea crear un conjunto de clases que CRUD a la base de datos para usted y devuelva objetos POCO limpios a ViewModel.

Un buen ejemplo para mirar sería el libro Nerd Dinner. Cubre MVC no MVVM pero los patrones son muy similares y la forma en que acceden a los datos en esa solución sería un buen punto de partida.

Espero que esto ayude.

+2

Gracias. Me gusta la forma en que Nerd Dinner usa el patrón Repository (como también sugiere Kristoffer). En términos de estructura de archivos, creo que separaré la clase Repository y los mapeadores asociados en un directorio de acceso a datos. Todavía parece que es una gran área que va enormemente mencionada en MVVM. Gracias de nuevo. –

+0

El ejemplo de NerdDinner es de hecho un buen ejemplo del patrón de repositorio. Sin embargo, exponen el modelo de dominio en las vistas (es decir, no usan MVVM), lo que se considera una mala práctica. – Kristoffer

+0

@ Lukasz, en la cena de nerd llaman directamente a los métodos sql. ¿Eso está bien? ¿Los modelos serían las clases generadas frol linqtosql? –

5

MVVM significa Modelo, Ver y modelo de vista. La pieza que te falta es el Modelo, que es donde vive tu código de acceso a datos.

El modelo de vista toma el modelo y lo presenta a la vista de la pantalla, por lo que normalmente tendría algo como esto:

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

El PersonView entonces unirse a las propiedades de la PersonViewModel en lugar de directamente a la modelo en sí. En muchos casos, es posible que ya tenga una capa de acceso a datos que no sabe nada de MVVM (y tampoco debería), pero aún puede construir ViewModels para presentarla en la vista.

+1

Elija este. –

+0

Consulte http://jonas.follesoe.no/YouCardRevisitedImplementingTheViewModelPattern.aspx –

+0

. Vale la pena señalar que esto sería difícil de implementar en escenarios de múltiples bases de datos, ya que tendría que pasar el contexto db al modelo. Esta es una razón principal por la que fuimos con el patrón de repositorio ... teniendo el CRUD en una biblioteca de clases separada. Su kilometraje variará. –

10

El acceso a los datos debe ser no en el modelo de vista, ya que se supone que es una representación específica de la vista (posiblemente simplificada) del modelo de dominio.

Use un mapeador de algún tipo para asignar su modelo de vista (la VM en MVVM) a su modelo (la primera M). Se pueden crear objetos nuevos en su modelo usando el patrón de fábrica. Una vez creado, puede almacenarlos en una base de datos utilizando el patrón de repositorio. Los repositorios representarían entonces su capa de acceso a datos. En su repositorio puede usar un asignador O/R como NHibernate o Entity Framework.

EDIT:
veo que GraemeF sugiere poner el código de acceso a datos en el modelo. Este es un NOT un buen enfoque, ya que esto le obligaría a actualizar su modelo de dominio si tuviera que pasar de, por ejemplo, SQL Server a Oracle o archivos XML. Los objetos de dominio no deberían tener que preocuparse por cómo se conservan. El patrón de repositorio aísla el dominio de su persistencia.

+1

Buen punto; por supuesto, puedes llevarlo mucho más lejos. Mi punto es que el código de acceso a datos está oculto detrás de esa interfaz y no vive en ViewModel. – GraemeF

1

Su ViewModel debe ser una capa delgada que solo sirve para la vista. Mi regla general: si tiene que ver con la presentación de la interfaz de usuario, entonces pertenece al ViewModel, de lo contrario debería estar en el modelo.

40

Así es como he estado organizando mi MVVM proyectos LINQ w /:

Modelo - pienso en el modelo que el estado del sistema. Proporciona una interfaz para los datos y realiza un seguimiento del estado del sistema. El Modelo no conoce el ViewModel o la Vista; solo proporciona una interfaz pública para sus datos y varios eventos para que los consumidores (generalmente ViewModels) sepan cuándo ha cambiado el estado.

modelo de vista - El modelo de vista es el encargado de organizar o estructurar todos los datos que necesita el Ver, hacer el seguimiento de la situación de la vista (por ejemplo, la fila seleccionada de una cuadrícula de datos), y respondiendo a las acciones en la vista (como presionar un botón). Sabe lo que la vista necesita, pero en realidad no sabe sobre la vista.

Ver - La vista es el aspecto real de la interfaz de usuario. Contiene todos los controles incorporados y personalizados, cómo se organizaron y cómo se diseñaron. Conoce el ViewModel, pero solo con el propósito de enlazar sus propiedades.

Puerta de enlace - Esta es la parte que aborda directamente su pregunta. La puerta de enlace (que es básicamente mi forma de decir "DataAccessLayer") es su propia capa separada. Contiene todo el código (incluidas las consultas LINQ) para CRUD o selecciona, inserta, actualiza y elimina datos desde/hacia su origen de datos (base de datos, archivo XML, etc.). También proporciona una interfaz pública para el Modelo, que permite al Modelo centrarse en mantener el estado del sistema sin tener que preocuparse por los detalles (es decir, las consultas) necesarios para actualizar el origen de datos.

Clases de acceso a datos - En C#, estas son clases muy simples que modelan sus objetos de datos elementales. Cuando selecciona algo utilizando una consulta LINQ, normalmente creará un IEnumerable<T> o List<T> donde T es uno de sus objetos de datos. Un ejemplo de un objeto de datos sería:

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

La gran ventaja de un diseño como este es que realmente separa a sus preocupaciones. Todo tiene un trabajo especializado, y es (generalmente) bastante fácil saber qué tipo de cosas van a dónde.

La desventaja es que puede ser excesivo para proyectos pequeños. Terminas creando una gran cantidad de infraestructura para interfaces públicas que básicamente pasan un solo deseo a través de varias capas. Por lo tanto, puede terminar con un escenario como este: [el usuario hace clic en Enviar, ViewModel le dice a Modelo que agregue NuevaPersona, Modelo le dice a Gateway en InsertPersona] en lugar de un escenario como este [usuario hace clic en Enviar, ViewModel agrega un nuevo registro a la base de datos directamente].

Espero que ayude.

+7

podría dar un breve ejemplo de su interpretación de mvvm porque siempre llegué a callejones sin salida si buscaba buenas soluciones DAL – WiiMaxx

2

El WPF Application Framework (WAF) contiene una aplicación de ejemplo que muestra cómo el patrón Model-View-ViewModel (MVVM) podría ser utilizado en combinación con el marco de la entidad.

Cuestiones relacionadas