Ho un paio di domande sui modelli di visualizzazione MVVM. Ho 3 modelli di visualizzazione nel mio scenario, che ho messo insieme un esempio più breve di seguito. Stavo cercando una soluzione per 3 viste che funzionasse in combinazione tra loro in una piccola parte di una grande applicazione. Ci sono 3 classi in gioco qui:
ParentViewModel
Rappresenta una vista che presenta una casella combinata con l'origine di MyLookups all'utente per selezionare un valore e archiviarlo in SelectedLookup.
C'è un pulsante che invocherà ShowDialogCommand che mostrerà il DialogVM1 tramite IDialogService.
DialogViewModel
Rappresenta una vista in cui l'utente immetterà alcune informazioni sul campo in NewItemTemplate. Quando fanno clic su OK, la finestra di dialogo si chiuderà e NewItemTemplate viene passato a ChildVM1 chiamando SetSomeInformation.
ChildViewModel
All'interno di ChildViewModel i dati del modello vengono quindi trasformati in un elenco di dati, ma ciò è irrilevante. ChildViewModel fornisce una griglia in cui l'utente può modificare un elenco di SomeData. La ricerca DefaultItem viene popolata da una combo nella griglia la cui origine dati è MyLookups.
IViewModelLocatorService
Questo utilizza il mio contenitore IoC per ottenere l'istanza di visualizzazione. Le viste stesse hanno un numero variabile di dipendenze del servizio. La proposta di IViewModelLocatorService doveva creare la mia istanza di visualizzazione quando ne avevo bisogno. Tuttavia, mentre sto scrivendo questo post, penso che potrei semplicemente iniettare l'istanza della vista nel costruttore ParentViewModel. Tutti i miei modelli di visualizzazione sono registrati nel contenitore IoC.
ILookupService
Il suo scopo è compilare un elenco di elementi che verranno visualizzati come una casella combinata su tutte e 3 le visualizzazioni. FindAll colpisce fondamentalmente il database (chiamando Entity Framework) e popola una nuova lista. Ciò crea ogni volta un nuovo DbContext. Al momento la ricerca non ha la precedenza su Equals, quindi anche se i dati saranno gli stessi in base all'Id, ma x == y sarebbe falso, quindi quando i dati vengono passati, sto lavorando con 3 elenchi diversi.
Attualmente tutti i servizi sono registrati come singleton.
public class ParentViewModel
{
private readonly ILookupService _lookupService;
private readonly ISomeService _someService;
private readonly IViewModelLocatorService _vmLocatorService;
private readonly IDialogService _dialogService;
public ParentViewModel(
ILookupService lookupService,
ISomeService someService,
IViewModelLocatorService vmLocatorService,
IDialogService dialogService,
ChildViewModel1 ChildViewModel // should we inject this?
)
{
...
MyLookups = _lookupService.FindAll(); // actually done from a load command but added here for simplicity sake
}
public ChildViewModel1 { get; private set; }
public ObservableCollection<Lookup> MyLookups { get; set; }
public Lookup SelectedLookup { get; private set; }
public ICommand ShowDialogCommand => new RelayCommand(
execute: () =>
{
// I want to show DialogViewModel here
var dialogVM = new DialogViewModel(...);
var dialogVM = _vmLocatorService.NewInstance<DialogViewModel>();
dialogVM.DefaultLookup = this.SelectedLookup;
_dialogService.Show(dialogVM, this);
if (dialogVM.DialogResult == true)
{
// pass some information to the child VM
ChildViewModel1.SetSomeInformation(dialogVM.NewItemTemplate);
}
},
canExecute: () => true);
}
public class ChildViewModel1
{
private readonly ILookupService _lookupService;
public ChildViewModel1(ILookupService lookupService)
{
...
MyLookups = _lookupService.FindAll();
}
public void SetSomeInformation(Lookup newLookupSelection)
{
...
}
public ObservableCollection<Lookup> MyLookups { get; set; }
}
public class DialogViewModel
{
private readonly ILookupService _lookupService;
private readonly ISomeOtherService1 _someOtherService1;
private readonly ISomeOtherService2 _someOtherService2;
public DialogViewModel(ILookupService lookupService, ISomeOtherService1 someOtherService1, ISomeOtherService2 someOtherService2)
{
...
MyLookups = _lookupService.FindAll(); // actually done from a load command but added here for simplicity sake
}
public SomeData NewItemTemplate { get; private set; }
public ObservableCollection<Lookup> MyLookups { get; set; }
}
public class SomeData
{
public long Id { get; set; }
public string Name { get; set; }
public Lookup DefaultItem { get; set; }
...
}
Le mie domande sono:
-
IViewModelLocatorService è un modo ragionevolmente valido per ottenere un'istanza del modello di visualizzazione in un modello di vista o è meglio mantenere esplicita la dipendenza iniettando il modello di vista figlio come dipendenza del costruttore? Ho letto cose su questa pratica negativa in passato, anche se non riesco a trovare nulla dopo una rapida occhiata stasera.
-
Con ILookupService, ci sono attualmente 3 elenchi diversi, ognuno con praticamente gli stessi dati. C'è un buon modo per fare in modo che le 3 viste utilizzino lo stesso elenco di dati? L'unica idea che ho è di impostare forzatamente la lista su DialogVM e ChildViewModel tramite una proprietà.