Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Using Unit of Work design pattern / NHibernate Sessions in an MVVM WPF

I think I am stuck in the paralysis of analysis. Please help!

I currently have a project that

  • Uses NHibernate on SQLite
  • Implements Repository and Unit of Work pattern: http://www.nhforge.org/wikis/patternsandpractices/nhibernate-and-the-unit-of-work-pattern.aspx
  • MVVM strategy in a WPF app

Unit of Work implementation in my case supports one NHibernate session at a time. I thought at the time that this makes sense; it hides inner workings of NHibernate session from ViewModel.

Now, according to Oren Eini (Ayende): http://msdn.microsoft.com/en-us/magazine/ee819139.aspx

He convinces the audience that NHibernate sessions should be created / disposed when the view associated with the presenter / viewmodel is disposed. He presents issues why you don't want one session per windows app, nor do you want a session to be created / disposed per transaction. This unfortunately poses a problem because my UI can easily have 10+ view/viewmodels present in an app. He is presenting using a MVP strategy, but does his advice translate to MVVM?

Does this mean that I should scrap the unit of work and have viewmodel create NHibernate sessions directly? Should a WPF app only have one working session at a time? If that is true, when should I create / dispose a NHibernate session?

And I still haven't considered how NHibernate Stateless sessions fit into all this! My brain is going to explode. Please help!

Update:

I found Ayende's Unit of Work implementation in Rhino Tools. I discovered that there are significant differences between his implementation and the one I did. His definitely supported multiple sessions. After further research I think it is best that I do the following:

  • Scrap my implementation of Unit of Work
  • Resign to using NHibernate's ISession and IStatelessSession objects directly from viewmodel. While in my opinion it's not ideal, I've already spent too much time on Unit of Work and it's not shaping up to what it is. Gotta apply KISS and YAGNI at some point. I can at least take solace in the fact that Ayende's article and a few others point out that using those directly is OK.
  • If I really really don't want to expose ISession, I can always use Castle.ActiveRecord, but I think that's not necessary.
  • I can re-use the Session Factory code, so the Unit of Work implementation is not a total waste.
  • Refactored my repositories to allow injection of both StatelessSession and Session, and use stateless if it's available: otherwise use regular session.

After all that, then I can apply the strategy of opening one session / stateless session per viewmodel and when view is disposed, have viewmodel flush / dispose the session / stateless session.

Sounds like a plan?

like image 733
Echiban Avatar asked Apr 09 '10 02:04

Echiban


3 Answers

I know this dates from a while ago but I've been looking online for a decent answer for 3 days. I read the two blogs you mention had a look at the Nhibernate 3.0 cookbook where they also talk about Nhibernate in a MVP application but this didn't fit exactly in my MVVM context with repositories and using Ninject for IoC.

I've found this old post which as so far been the most useful page: http://www.emidee.net/index.php/2010/08/23/ninject-use-one-database-session-per-view-model

I hope this helps anyone who will stumble upon this question in the future.

like image 58
Mat Avatar answered Nov 20 '22 08:11

Mat


What is your actual concern with having 10+ sessions active? Sessions are light-weight objects that can be used for heavy-weight operations. If the session isn't currently doing anything, it's kind of insignificant.

like image 23
Kent Boogaart Avatar answered Nov 20 '22 07:11

Kent Boogaart


Using UnitOfWork is seriously limiting in a client app, as all lazy-loading breaks. You lose part of what NHibernate is good at. You're also setting yourself up for runtime exceptions, because there is nothing in the NHibernate model to remind you not to use these features. I'd say Ayendes advice is good.

like image 22
Robert Jeppesen Avatar answered Nov 20 '22 09:11

Robert Jeppesen