2010-04-09 8 views
12

Penso di essere bloccato nella paralisi dell'analisi. Per favore aiuto!Uso del modello di progettazione dell'unità di lavoro/Sessioni NHibernate in un MVPM WPF

Al momento ho un progetto che

unità di lavoro l'implementazione nel mio caso supporta una sessione di NHibernate alla volta. All'epoca pensavo che questo avesse senso; nasconde il funzionamento interno della sessione di NHibernate da ViewModel.

Ora, secondo Oren Eini (Ayende): http://msdn.microsoft.com/en-us/magazine/ee819139.aspx

convince il pubblico che le sessioni NHibernate dovrebbero essere creati/smaltiti quando la vista associata con il presentatore/ViewModel è disposto. Presenta i problemi per cui non si desidera una sessione per app di Windows, né si desidera creare/disporre una sessione per transazione. Questo purtroppo pone un problema perché la mia interfaccia utente può facilmente avere oltre 10 view/viewmodels presenti in un'app. Sta presentando usando una strategia MVP, ma i suoi consigli si traducono in MVVM?

Ciò significa che dovrei eliminare l'unità di lavoro e fare in modo che viewmodel crei direttamente le sessioni di NHibernate? Un'app WPF dovrebbe avere solo una sessione di lavoro alla volta? Se ciò è vero, quando dovrei creare/disporre una sessione di NHibernate?

E non ho ancora considerato in che modo le sessioni stateless di NHibernate si adattino a tutto questo! Il mio cervello sta per esplodere. Per favore aiuto!

Aggiornamento:

ho trovato Unità di Ayende di implementazione Work in Rhino Tools. Ho scoperto che ci sono differenze significative tra la sua implementazione e quella che ho fatto. Sicuramente ha supportato più sessioni. Dopo ulteriori ricerche penso che sia meglio che faccio la seguente:

  • rottami mia implementazione di unità di lavoro
  • rassegnarsi a utilizzare ISession di NHibernate e IStatelessSession oggetti direttamente dal ViewModel. Mentre a mio parere non è l'ideale, ho già passato troppo tempo sull'unità di lavoro e non si presta a quello che è. Devo applicare KISS e YAGNI ad un certo punto. Posso almeno prendere confidenza nel fatto che l'articolo di Ayende e alcuni altri sottolineano che l'uso diretto di questi è OK.
  • Se davvero non voglio esporre ISession, posso sempre usare Castle.ActiveRecord, ma penso che non sia necessario.
  • Posso riutilizzare il codice Session Factory, quindi l'implementazione dell'unità di lavoro non è uno spreco totale.
  • Refactored i miei repository per consentire l'iniezione sia di StatelessSession che di Session e utilizzare stateless se è disponibile: altrimenti utilizzare la sessione regolare.

Dopo tutto questo, allora può applicare la strategia di aprire una sessione/sessione senza per viewmodel e quando vista è disposto, avere filo viewmodel/smaltire il/sessione stateless session.

Suona come un piano?

+0

Il primo collegamento è morto – afaolek

risposta

2

Qual è la tua preoccupazione per avere più di 10 sessioni attive? Le sessioni sono oggetti leggeri che possono essere utilizzati per operazioni pesanti. Se la sessione non sta attualmente facendo nulla, è un po 'insignificante.

+0

Il mio problema è che ho iniziato scrivendo repository, quindi mi rendo conto che un'unità di lavoro si aggiungerebbe ai repository perché non voglio esporre il funzionamento di NHibernate ai viewmodels (non ero al 100% venduto su Nibernate quindi), quindi l'ho fatto. Ora sembra che la mia unità di implementazione del lavoro non sia buona perché quella particolare implementazione supporta solo una sessione alla volta. Forse la risposta sta nel dover refactoring Unit Of Work per supportare più sessioni. A volte vorrei non essermi preoccupato dell'Unità di lavoro e ho usato subito le sessioni di NHibernate. Sta iniziando a puzzare. – Echiban

+0

Penso che in questo momento abbia bisogno di una guida su come dovrebbe apparire una corretta unità di implementazione del lavoro. La mia attuale implementazione è molto vicina al link dell'unità di lavoro sopra. – Echiban

1

Utilizzo di UnitOfWork è un limite grave in un'app client, come tutte le interruzioni di caricamento lento. Perdi una parte di ciò in cui NHibernate è bravo. Stai anche impostando te stesso per le eccezioni di runtime, perché non c'è nulla nel modello di NHibernate che ti ricordi di non usare queste funzionalità. Direi che il consiglio di Ayendes è buono.

+1

Spiegare perché un UnitOfWork (fondamentalmente l'ISS di nH) rompe il caricamento lento? – tofi9

+0

L'unità di lavoro, il modo in cui l'ho implementata, consente solo una sessione attiva alla volta. Secondo l'articolo sull'unità di lavoro, ho letto che era buono sia per il cliente che per il web, quindi sono andato avanti e l'ho fatto. Ora sto arrivando alla conclusione che la mia unità di lavoro necessita di una grande riscrittura per supportare più sessioni. – Echiban

+0

@taoufik: Un'unità di lavoro è di breve durata (e uccide la sessione quando tutto il lavoro è terminato). L'entità che stai recuperando rischia di sopravvivere a UnitOfWork. Qualsiasi proxy che carica pigro manterrà un riferimento alla sessione che ora viene uccisa. Se si tenta di utilizzare qualsiasi proprietà di caricamento lazy al di fuori di UnitOfWork, si verificano eccezioni di runtime. –

0

Personalmente cerco di mantenere le sessioni aperte per il minor tempo possibile. Il motivo principale è che utilizziamo il blocco pessimistico sulla nostra principale radice di aggregazione (stiamo utilizzando la progettazione basata sul dominio), quindi vogliamo rilasciare il blocco il più rapidamente possibile. Non dimenticare che dal momento che stai utilizzando il lato client di NHibernate puoi chiudere la sessione e quando ne apri una nuova puoi ricollegare le entità disconnesse.

Personalmente, anche in un'app con più finestre/schede aperte in una sola volta, usavo ancora una sola sessione alla volta. Vorrei aprirne una nuova quando ho bisogno di recuperare i dati per una vista o quando le modifiche devono essere persistenti.

A un certo punto della nostra attuale applicazione abbiamo implementato il supporto multisessione nella nostra Unità di lavoro, ma alla fine l'abbiamo rimosso quando ci siamo resi conto di non averne alcuna utilità e ha solo complicato le cose.

3

Conosco questa data da un po 'di tempo fa ma ho cercato online una risposta decente per 3 giorni. Ho letto i due blog che hai menzionato nel libro di cucina Nhibernate 3.0 in cui parlano anche di Nhibernate in un'applicazione MVP, ma questo non si adattava esattamente al mio contesto MVVM con repository e usando Ninject per IoC.

ho trovato questo vecchio post che, come finora stata la pagina più utile: http://www.emidee.net/index.php/2010/08/23/ninject-use-one-database-session-per-view-model

Spero che questo aiuta chiunque voglia inciampare su questa domanda in futuro.