2011-06-29 11 views
10

Soy bastante nuevo en MVVM, así que discúlpeme si este problema tiene una solución conocida.Propiedades no bloqueadas de carga lenta en el modelo de MVVM

Estamos construyendo un conjunto de clases de modelos que tienen algunas propiedades centrales que se cargan por adelantado, así como algunas propiedades adicionales que podrían cargarse de forma diferida a pedido haciendo una llamada a la API web (actualización: para aclarar, sería una llamada a la API web por cada propiedad cargada de forma lenta).

En lugar de tener varios modelos, parece sensato tener un solo modelo con la lógica de carga diferida allí. Sin embargo, también parece que las propiedades de carga diferida no deben bloquearse cuando se accede, de modo que cuando la Vista se vincula al ViewModel y se une al Modelo, no bloqueamos el subproceso de UI.

Como tal, yo estaba pensando en un patrón algo en la línea de cuando se accede a una propiedad de descanso en el modelo comienza una búsqueda asíncrona y luego regresa inmediatamente a un valor predeterminado (por ejemplo null). Cuando se completa la recuperación asíncrona, se generará un evento PropertyChanged para que ViewModel/View pueda vincularse al valor recuperado.

que he probado esto y parece que funciona bastante bien, pero se preguntaba:

  1. ¿Hay trampas a este enfoque que no he descubierto acerca aún, pero se encontrará con tan la aplicación aumenta en complejidad?
  2. ¿Existe una solución existente a este problema, ya sea integrada en el marco, o que se usa ampliamente como parte de un marco de terceros?
+0

El posible problema que se me puede ocurrir, es que necesita escuchar el evento PropertyChanged en todos estos cargadores perezosos, lo que significa que si tiene una propiedad o función que depende de varios de estos cargadores, tendrá que espere a que terminen todos los cargadores en los que confía antes de ejecutar su propio código. Esto podría dar como resultado tener que escribir una gran cantidad de lógica que, de otro modo, podría haber sido escrita como una sola llamada con subprocesos que combina la búsqueda de los cargadores perezosos "sincrónicamente" dentro de ese subproceso separado. –

+0

@Timothy - Buen punto. Ya he pensado sobre eso, y tengo la sensación de que, debido a la naturaleza de los datos cargados de forma perezosa, es poco probable que algo dependa de múltiples datos perezosos. Es probable que varias cosas dependan de una sola pieza de datos perezosos, pero no creo que eso represente un problema. –

+0

Uso el enfoque exacto que describes arriba y funcionó muy bien. – Jeff

Respuesta

6

Hice algo así en el pasado y lo único que olvidé es que no puede llamar a su propiedad asíncrona mediante ningún tipo de código y esperar que tenga un valor.

Así que si lazy-load una lista de Customer.Products, no puedo hacer referencia Customer.Products.Count en el código subyacente porque la primera vez que se llama el valor es NULL o 0 (dependiendo de si creo una colección en blanco o no)

Aparte de eso, funcionó muy bien para las fijaciones. Estaba usando la biblioteca Async CTP para realizar mis llamadas asíncronas, lo que encontré fue maravilloso para algo como esto.

public ObservableCollection<Products> Products 
{ 
    get 
    { 
     if (_products == null) 
      LoadProductsAsync(); 

     return _products; 
    } 
    set { ... } 
} 

private async void LoadProductsAsync() 
{ 
    Products = await DAL.LoadProducts(CustomerId); 
} 

actualización

Recuerdo otra cosa que tenía era problemas con los datos que realmente era nulo. Si Customer.Products realmente devolvió un valor NULL del servidor, necesitaba saber que el método async se había ejecutado correctamente y que el valor real era nulo para que no volviera a ejecutar el método async.

Tampoco quería que el método asíncrono se ejecutara dos veces si alguien llamaba al método Get una segunda vez antes de que se completara la primera llamada asíncrona.

He resuelto esto en el tiempo por tener un Is[AsyncPropertyName]Loading/ed propiedad para cada propiedad asíncrono y se establece en verdadero durante la primera llamada asincrónica, pero no estaba muy feliz por tener que crear una propiedad adicional para todas las propiedades asincrónicos.

+0

* (Agregado de resaltado de sintaxis) * –

Cuestiones relacionadas