2010-04-27 11 views
10

Actualmente estoy trabajando en lo que será mi primera incursión real en el uso de MVVM y he leído varios artículos sobre la mejor manera de implementarlo.¿Debo usar DTO como mis modelos de datos en MVVM?

Mis pensamientos actuales son usar mis modelos de datos de manera efectiva como objetos de transferencia de datos, hacerlos serializables y tenerlos tanto en el lado del cliente como del servidor. Parece un paso lógico ya que ambos tipos de objetos son realmente colecciones de captadores de propiedades y definidores, y otra capa intermedia parece ser una exageración completa.

Obviamente, habría problemas con INotifyPropertyChanged que no funcionaba correctamente en el servidor ya que no hay ViewModel para comunicarse, pero siempre que tengamos cuidado al construir nuestros objetos de modelo de dominio correctos a partir de modelos de datos en la capa de servicio y no tratando los modelos de datos del lado del servidor. No creo que deba ser un gran problema.

No he encontrado demasiada información sobre este enfoque en mi lectura, por lo que me gustaría saber si esto es algo bastante estándar, ¿se supone que es la manera de facto de hacer MVVM en una entorno de nivel? Si tengo una idea completamente equivocada sobre las cosas, también se valorarán las ideas sobre otros enfoques.

Respuesta

2

No soy experto en esto. Yo tenía el mismo escenario. Estoy de acuerdo contigo en que eso es bastante exagerado. He estado utilizando esta solución desde hace bastante tiempo y no he encontrado ningún problema. El INotifyPropertyChanged no es un gran problema para mí, ya que nada en el servidor se suscribirá al evento PropertyChanged. Si va a utilizar la herencia en sus modelos de datos, entonces todos deben ser serializables. En mi caso, tengo dos clases base para mis modelos de datos: una que se usa para la transferencia de datos, y la otra no.

+0

Gracias, parece que no hay un consenso realmente definido en este momento. Dado que ya has hecho algo similar sin problemas, aceptaré este como respuesta. – JonC

5

Puede usar cualquier modelo con el que se sienta cómodo, sí, todas sus propiedades necesitarán el comportamiento INotifyPropertyChanged. Cómo afectará esto a la capa de servicio depende totalmente de su implementación.

Supongo que usted indica que se une a su DTO en su punto de vista?

Como veo es que hay una falta de coincidencia de impedancia entre las capas de la aplicación, es decir, su modelo de dominio probablemente se parece a su modelo relacional, con diferencias sutiles pero cruciales. También existe una discrepancia entre el Modelo de Dominio y su DTO (los objetos pueden ser aplanados, propiedades calculadas, etc., ...). Es tentador vincularse directamente con los DTO, ya que probablemente estén diseñados para tener lo que necesita para la operación en particular, sin embargo, también existe una falta de coincidencia de impedancia entre el DTO y lo que necesita la vista para lograr el resultado deseado. Aquí es donde entra en juego el modelo de vista. El modelo de vista tiene la responsabilidad de transmitir las propiedades de DTO a la vista, es responsable de informar a la vista si hay errores de validación y enruta los comandos al controlador apropiado (Guardar, Eliminar, etc. , ...).

que tienden a establecer las cosas de la manera siguiente:

// POCO object. Serializable. 
public class AddressDto 
{  
    public int Id { get; set; } 
    public string Street { get; set; }  
    public string City { get; set; }  
    public string Country { get; set; } 
} 

// IDataErrorInfo for validation. 
public class AddressViewModel : INotifyPropertyChanged, IDataErrorInfo 
{ 
    private readonly AddressDto addressDto; 

    public AddressViewModel(AddressDto addressDto) 
    { 
     this.addressDto = addressDto;  
    } 

    public int Id { /* get and set for property changed event and update dto */ } 
    public string Street { /* get and set for property changed event and update dto */ } 
    public string City { /* get and set for property changed event and update dto */ } 
    public string Country { /* get and set for property changed event and update dto */ } 
    ... 

    // IDataErrorInfo implementation 
} 

public class EditAddressViewModel : INotifyPropertyChanged 
{ 
    public AddressViewModel Address { /* get and set for property changed event */ } 
    public ICommand Save { /* setup command */ } 
    public ICommand Cancel { /* setup command */ } 

    private void Save() 
    { 
    } 

    private void Cancel() 
    { 
    } 
} 

Su EditAddressView entonces unirse al EditAddressViewModel. Básicamente, la regla es que todo su comportamiento de UI debe expresarse en términos de su modelo de vista.

Sí, eso significa trabajo adicional, aunque hay cosas que puede hacer para simplificar un poco las cosas (generación de código, etc.). De hecho, estoy trabajando en una biblioteca que pretende simplificar todo el proceso MVVM utilizando una API apta.Compruébelo en http://fluentviewmodel.codeplex.com/

1

Decidí tener una propiedad "Modelo" en mi ViewModel. En el modelo en sí, ya implementé IPropertyNotifyChanged e IDataErrorInfo. En mi ViewModel, omito las propiedades en las que el código simplemente "caería" en el modelo. En cambio, la Vista se une directamente al modelo para esas propiedades.

Para casos más complicados, donde tengo que ajustar los datos en el modelo para que se ajusten a la vista, lo hago en ViewModel. Además, los comandos, etc. están en ViewModel. Pero no veo la razón para tener un código repetitivo en ViewModel repitiendo las mismas cosas que ya tengo en el modelo.

Cuestiones relacionadas