Non mi è chiaro come sia possibile progettare in modo da mantenere il riferimento al contenitore DI nella radice di composizione per un'applicazione Silverlight + MVVM.Mantenere l'utilizzo del contenitore di DI nella radice composizione in Silverlight e MVVM
Ho il seguente scenario di utilizzo semplice: c'è una vista principale (forse un elenco di elementi) e un'azione per aprire una vista di modifica per un singolo elemento. Pertanto, la vista principale deve creare e mostrare la vista di modifica quando l'utente esegue l'azione (ad esempio, fa clic su un pulsante).
Per questo ho il seguente codice:
public interface IView
{
IViewModel ViewModel {get; set;}
}
Poi, per ogni visualizzazione che ho bisogno di essere in grado di creare Ho una fabbrica di astratto, in questo modo
public interface ISomeViewFactory
{
IView CreateView();
}
Questa fabbrica è poi dichiarato una dipendenza del modello di vista "padre", in questo modo:
public class SomeParentViewModel
{
public SomeParentViewModel(ISomeViewFactory viewFactory)
{
// store it
}
private void OnSomeUserAction()
{
IView view = viewFactory.CreateView();
dialogService.ShowDialog(view);
}
}
quindi va tutto bene fin qui, nessuna dI -container in vista :). Ora arriva la realizzazione di ISomeViewFactory:
public class SomeViewFactory : ISomeViewFactory
{
public IView CreateView()
{
IView view = new SomeView();
view.ViewModel = ????
}
}
Il "????" parte è il mio problema, perché il modello di vista per la vista deve essere risolto dal contenitore DI in modo da ottenere le sue dipendenze iniettate. Quello che non so è come posso farlo senza avere una dipendenza dal DI-container ovunque tranne la radice della composizione.
Una possibile soluzione sarebbe quella di disporre di una dipendenza dal modello di vista che viene iniettato nella fabbrica, in questo modo:
public class SomeViewFactory : ISomeViewFactory
{
public SomeViewFactory(ISomeViewModel viewModel)
{
// store it
}
public IView CreateView()
{
IView view = new SomeView();
view.ViewModel = viewModel;
}
}
Mentre questo funziona, ha il problema che, poiché il grafico intero oggetto è cablato "staticamente" (cioè il modello di visualizzazione "genitore" otterrà un'istanza di SomeViewFactory, che otterrà un'istanza di SomeViewModel, e questi vivranno fino a quando il modello di visualizzazione "genitore" vive), l'implementazione del modello di vista iniettato è stateful e se l'utente apre la vista figlio due volte, la seconda volta il modello di vista sarà la stessa istanza e avrà lo stato di prima. Immagino di poter aggirare questo problema con un metodo "Initialize" o qualcosa di simile, ma non ha un buon odore.
Un'altra soluzione potrebbe essere quella di avvolgere il DI-contenitore e hanno le fabbriche dipendono l'involucro, ma sarebbe ancora un DI-contenitore "in incognito" ci :)
ps: la mia soluzione attuale è che le fabbriche conoscono il DI-container, e sono solo loro e la radice di composizione ad avere questa dipendenza.
Grazie mille. Anche se la tua implementazione è cristallina, quello che ho fatto è stato semplicemente dichiarare le dipendenze per il modello di visualizzazione sulle mie fabbriche, in quanto sono davvero molto semplici e ho sentito che avere qualcosa come il tuo View Populator è eccessivo per me. Eppure, da un punto di vista SOLIDO e soprattutto se le cose si complicano, separare la responsabilità come hai fatto ha sicuramente molto senso. Grandi cose :) –
Felice di essere di aiuto :) –