views:

298

answers:

1

Hi all

Im really struggling with NHibernate here. I'm trying to keep my DAL-assembly very generic, so that it works in a webcontext, in WCF and in WinForms / WPF. My problem here is the sessions.

Lazy-loading is good, and something I really want, but after the session which you loaded the object with is closed, you can't lazy-load anymore. This turns out to be a huge deal for me, since I don't know in which scope I should start / end my sessions.

I've seen a lot of people starting them on HttpContext.Begin and ending them on .End, but this is not feasable for me, since I don't want my assembly to link to System.Web or be bound to be called in a HttpContext.

Another option would be to just keep one session for the entire DAL-assembly lifecycle. What are some pros and cons onto this approach? The assembly will mainly work as a backend in a website, but also do some work for a WinForms application.

Any takers? :)

[EDIT] Another option for me would be to write my own lazy-loading proxy-collections, which in turn would open a new session and fetch whatever data the collection should contain. Any comments on this approach?

+1  A: 

In our system we have the concept of a unit of work. A unit of work to us is a single operation against the system. For instance withdrawing money from an account or depositing money into an account would be a single unit of work.

The unit of work class wraps the NHibernate session (and a few other things) and then our Repositories work against the current unit of work (via thread storage).

In terms of what you're trying to do we would then do the following...

  • For WCF we have a UnitOfWorkContext attribute which we apply to an operation that is responsible for beginning/ending the unit of work.

  • For WinForms we would just have the presenter begin/end a unit of work

  • For WebContext we would do the same in HttpContext.Begin and .End

ShaneC
Sounds great. I was thinking something like that as well, but what if the "Unit of work" can be 3x "Withdrawing money" + 1x "Depositing money"? :)
cwap
Not sure I understand what you mean exactly. You mean they withdraw and deposit money at the same time? In that case I would probably create a new operation that calls both operations and is wrapped in a single unit of work. A good way to think of a unit of work is that it should wrap everything you need to undo one operation so you can do a single UnitOfWork.Rollback().
ShaneC
Makes perfect sense. I'm just afraid that I'll end up with a huuuuge amount of Units of Work. How does this cope with your experience ?
cwap
In our system we only allow one unit of work per thread at one time. We're also WCF based so adding UnitOfWorkContext attribute to an OperationContext is not a big deal.
ShaneC