Chiedo scusa per la lunga domanda, che legge un po 'come uno sfogo, ma prometto che non lo è! Di seguito ho riassunto le mie domande
Nel mondo MVC, le cose sono semplici. Il modello ha stato, la vista mostra il modello e il controller fa cose al / con il modello (in pratica), un controller non ha stato. Per fare cose il Controller ha alcune dipendenze dai servizi web, dal repository, dal lotto. Quando si crea un'istanza di un controller, ci si preoccupa di fornire tali dipendenze, nient'altro. Quando si esegue un'azione (metodo sul controller), si utilizzano tali dipendenze per recuperare o aggiornare il modello o chiamare un altro servizio di dominio. Se c'è qualche contesto, supponiamo che alcuni utenti vogliano vedere i dettagli di un particolare oggetto, si passa l'ID di quell'elemento come parametro all'Azione. Da nessuna parte nel controller c'è alcun riferimento a qualsiasi stato. Fin qui tutto bene.
Inserisci MVVM. Adoro WPF, adoro l'associazione dei dati. Adoro i framework che rendono ancora più semplice l'associazione dei dati a ViewModels (utilizzando Caliburn Micro atm). Sento che le cose sono meno semplici in questo mondo però. Facciamo l'esercizio di nuovo: il modello è stato, la vista mostra il ViewModel, e il ViewModel fa roba per / con il modello (in pratica), un ViewModel fa avere stato! (per chiarire; forse delega tutte le proprietà di uno o più modelli, ma che significa che deve avere un riferimento al modello un modo o nell'altro, che è stato in sé) Per fareroba il ViewModel ha alcune dipendenze da servizi web, repository, il lotto. Quando si crea un'istanza di ViewModel, ci si preoccupa di fornire tali dipendenze, ma anche lo stato. E questo, onorevoli colleghi, mi infastidisce senza fine.
Ogni volta che devi istanziare a ProductDetailsViewModel
dal ProductSearchViewModel
(da cui hai chiamato il ProductSearchWebService
che a sua volta è tornato IEnumerable<ProductDTO>
, tutti sono ancora con me?), Puoi fare una di queste cose:
- chiama
new ProductDetailsViewModel(productDTO, _shoppingCartWebService /* dependcy */);
, questo è male, immagina altre 3 dipendenze, questo significa che anche iProductSearchViewModel
bisogni devono assumersi. Anche cambiare il costruttore è doloroso. - chiamata
_myInjectedProductDetailsViewModelFactory.Create().Initialize(productDTO);
, la fabbrica è solo un Func, sono facilmente generati dalla maggior parte dei framework IoC. Penso che questo sia negativo perché i metodi Init sono un'astrazione che perde. Inoltre, non è possibile utilizzare la parola chiave readonly per i campi impostati nel metodo Init. Sono sicuro che ci sono alcune ragioni in più. - chiama
_myInjectedProductDetailsViewModelAbstractFactory.Create(productDTO);
Quindi ... questo è il modello (fabbrica astratta) che di solito è raccomandato per questo tipo di problema. Ho pensato che fosse geniale poiché soddisfa la mia brama di scrittura statica, fino a quando non ho iniziato a usarlo. La quantità di codice boilerplate è che penso troppo (sai, a parte i ridicoli nomi delle variabili che uso). Per ogni ViewModel che necessita di parametri di runtime otterrai due file extra (interfaccia di fabbrica e implementazione) e dovrai digitare le dipendenze non di runtime come 4 volte extra. E ogni volta che cambiano le dipendenze, puoi cambiarle anche in fabbrica. Mi sembra di non usare più nemmeno un contenitore DI. (Penso che Castle Windsor abbia una sorta di soluzione per questo [con i suoi svantaggi, correggimi se sbaglio]). - fare qualcosa con tipi o dizionario anonimi. Mi piace la mia digitazione statica.
Quindi si La miscelazione di stato e comportamento in questo modo crea un problema che non esiste affatto in MVC. E sento che al momento non esiste una soluzione davvero adeguata per questo problema. Ora vorrei osservare alcune cose:
- Le persone usano effettivamente MVVM. Quindi o non si preoccupano di tutto quanto sopra, o hanno qualche altra brillante soluzione.
- Non ho trovato un esempio approfondito di MVVM con WPF. Ad esempio, il progetto di esempio NDDD mi ha aiutato immensamente a comprendere alcuni concetti di DDD. Mi piacerebbe davvero che qualcuno potesse indicarmi qualcosa di simile per MVVM / WPF.
- Forse sto sbagliando MVVM e dovrei capovolgere il mio design. Forse non dovrei avere questo problema. Beh, so che altre persone hanno posto la stessa domanda, quindi penso di non essere il solo.
Riassumere
- Ho ragione a concludere che avere ViewModel come punto di integrazione sia per stato che per comportamento è la ragione di alcune difficoltà con il modello MVVM nel suo insieme?
- L'uso del modello astratto di fabbrica è l'unico / miglior modo per creare un'istanza di un ViewModel in modo tipicamente statico?
- È disponibile qualcosa come un'implementazione di riferimento approfondita?
- Avere un sacco di ViewModels con sia stato / comportamento ha un odore di design?