Question

Je développe une application WPF en utilisant le modèle MVVM. J'utilise la bibliothèque MVVM légère et je suis également essayer d'utiliser un injecteur de dépendance (je considère Ninject et l'unité).

J'ai lu beaucoup d'articles de blog et je suis assez confus sur la façon de faire mes classes « bon » de communiquer entre eux. En particulier, je ne sais pas quand utiliser l'injection de dépendance et quand compter sur le modèle de médiateur.

Permet de considérer un exemple. J'ai un ViewModel, laisse appeler DataViewModel, et la classe de données qui fournit une sorte de données. Comment est-il préférable de communiquer entre eux:

A. Injecter une dépendance à DataViewModel avec une interface de IData? Cette façon dont les données ne seront pas compter sur Messenger, mais il devra fournir un événement si les modifications de données, et le ViewModel devront souscrire.

B. Fiez sur le modèle de médiateur (mis en œuvre dans MVVM lumière comme Messenger) et envoyer des messages entre le modèle et ViewModel? De cette façon, il ne sera pas nécessaire d'utiliser l'injection de dépendance du tout, parce que la communication tout sera basé sur des messages.

De plus, si mes ViewModels ont injecté des dépendances sur d'autres ViewModels, ou il serait préférable que de compter sur le messager? Si la première, serait-il nécessaire de définir une interface distincte pour chaque ViewModel? Je pense que la définition d'une interface pour chaque machine virtuelle sera un travail supplémentaire, mais peut-être cela vaut la peine.

Était-ce utile?

La solution

En général, le ViewModel va à un service (comme l'appelle Prism il) pour récupérer les données dont il a besoin. Ce service est poussé à la ViewModel via DI (injection Constructor) bien que vous pouvez effectuer cette autre façon par une ServiceLocator.

Par conséquent, votre ViewModel tiendra une référence à un service qui abstraire la récupération de vos données. Les données pourraient provenir d'une base de données, fichier XML, qui sait ... l'abstraction est là. Donc, pour votre cas de IData, la référence à ce type se produit à un moment donné dans le ViewModel mais pas au moyen d'une DI de de. Si votre cadre IoC permet (Prism ne) vous créez des applications types d'interface pour les types de béton, puis récupérer ces types via votre conteneur; tel est le cas avec l'unité.

Voici un bref exemple ... Scripts est lié à la vue et le ViewModel est injecté dans la vue. Notez l'utilisation du IScriptService pour récupérer les données. Les données à venir est de retour une collection de types iScript, mais nous injectons jamais formellement ce type dans le ViewModel parce que nous ne se soucient pas du type comme une seule entité que nous nous soucions du type à l'échelle de grandeur.

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

Lorsque vous faites votre chemin à la vue, le même cas peut être fait là-bas, la vue s'injecté par DI (injection Constructor) avec le ViewModel. Je ne voudrais pas faire d'autres ViewModels dépendent les uns des autres, les garder isolés. Si vous commencez à voir un besoin de couplage jeter un oeil à les données que vous essayez de partager, plus souvent qu'autrement à ces données doit être soustrait à plus loin et ne pas se coupler à un ViewModel.

Autres conseils

Il y a plus d'une bonne solution à votre problème,

Je vous suggère d'utiliser une interface unique dans vos modèles de données, le mettre dans une classe de base, cette interface permettra à vos objets de données de communiquer avec le monde extérieur.

Pour les modèles de vue injectent pas les données, mais une interface qui permet de récupérer des données pour vous, les données exposera les événements que le vm peut inscrire pour eux après qu'il les reçoit.

ojet de données ne devrait pas savoir qui le tient, le modèle de vue sait quel genre de données qu'il détient, mais je ne recommande pas d'injecter ces données en raison de problèmes de flexibilité.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top