2010-11-17 31 views
6

Estoy desarrollando una aplicación WPF usando el patrón MVVM. Estoy usando la biblioteca MVVM Light y también estoy tratando de usar un inyector de dependencia (estoy considerando Ninject y Unity).MVVM: comunicación entre el modelo y ViewModels

He leído muchos artículos de blog y estoy bastante confundido sobre la forma "correcta" de hacer que mis clases se comuniquen entre sí. En particular, no sé cuándo usar Dependency Injection y cuándo confiar en el patrón del mediador.

Consideremos un ejemplo. Tengo un ViewModel, vamos a llamarlo DataViewModel, y la clase de datos que proporciona algún tipo de datos. ¿Cómo es mejor comunicarse entre ellos:

A. ¿Inyectar una dependencia a DataViewModel con una interfaz de IData? De esta manera, Data no tendrá que depender de Messenger, pero tendrá que proporcionar un evento si los datos cambian y ViewModel tendrá que suscribirse.

B. ¿Confía en el patrón del mediador (implementado en MVVM Light como Messenger) y envía mensajes entre Model y ViewModel? De esta forma, no será necesario utilizar Inyección de Dependencia, ya que toda la comunicación se basará en los mensajes.

Además, ¿deberían mis ViewModels haber inyectado dependencias en otros ViewModels, o sería mejor simplemente confiar en el Messenger? Si es el primero, ¿sería necesario definir una interfaz separada para cada ViewModel? Creo que definir una interfaz para cada máquina virtual será un trabajo adicional, pero tal vez valga la pena.

Respuesta

4

Generalmente, ViewModel va a un servicio (como lo llama Prism) para recuperar los datos que necesita. Ese servicio se envía al ViewModel a través de DI (Inyección de constructor), aunque puede realizar esto de otra manera a través de un ServiceLocator.

Por lo tanto, su ViewModel tendrá una referencia a un servicio que abstraerá la recuperación de sus datos. Los datos podrían provenir de un archivo DB, XML, quién sabe ... la abstracción está ahí. Por lo tanto, para su caso de IData, la referencia a ese tipo ocurrirá en algún punto en el modelo de vista pero no a través de ninguno de DI. Si su marco de trabajo de IoC lo permite (Prism lo hace) crea mapeos de tipos de interfaz para tipos concretos y luego los recupera a través de su contenedor; tal es el caso de Unity.

Aquí hay un breve ejemplo ... Scripts está vinculado a la Vista y el Modelo de Vista se inyecta en la Vista. Observe el uso de IScriptService para recuperar los datos. Los datos que regresan son una colección de tipos de IScript, sin embargo, nunca hemos inyectado formalmente ese tipo en ViewModel porque no nos importa el tipo como entidad única, nos importa el tipo en una escala de grandeza.

 public ScriptRepositoryViewModel(IUnityContainer container, IScriptService scriptService, IEventAggregator eventAggregator) 
     { 
      _container = container; 
      _scriptService = scriptService; 
      _eventAggregator = eventAggregator; 
     } 

     public ICollectionView Scripts 
     { 
      get 
      { 
       if (_view == null) 
       { 
        _view = CollectionViewSource.GetDefaultView(_scriptService.Scripts); 
        _view.Filter = Filter; 
       } 

       return _view; 
      } 
     } 

Cuando usted hace su camino a la Vista, el mismo caso se puede tener allí, la vista conseguirá inyectada a través de DI (Inyección de Constructor) con el modelo de vista. No haría que otros ViewModels dependan el uno del otro, manténgalos aislados. Si comienza a ver la necesidad de un acoplamiento, eche un vistazo a los datos que intenta compartir, con mayor frecuencia los datos deben abstraerse y no acoplarse a ningún ViewModel.

+0

Ahora lo entiendo ... pero necesitaba un poco de tiempo para acostumbrarme a la inyección de dependencia y los servicios :) ¡Gracias! – madbadger

1

Hay más de una buena solución a su problema,

sugiero que use alguna de las interfaces solo en sus modelos de datos, lo puso en una clase base, esta interfaz permitirá que sus objetos de datos que se comunican con el mundo exterior.

Para que los modelos de vista no inyecten los datos, sino una interfaz que pueda recuperar datos para usted, los datos expondrán los eventos que la vm puede registrar después de que los obtenga.

oye de datos no debe saber quién lo tiene, el modelo de vista sabe qué tipo de datos tiene, pero no recomiendo inyectar estos datos debido a problemas de flexibilidad.

Cuestiones relacionadas