How to handle Session in WinForm project?

244 views
Skip to first unread message

ChrisHolmes

unread,
Aug 22, 2009, 12:25:56 PM8/22/09
to nhusers
Hey gang,

I'm trying to figure out the best way to handle the NHibernate session
in a WinForm scenario. I've Googled this to death and I still can't
find anything that makes sense and I haven't found any actual code
that I can read and make sense out of. I've read a lot about Session-
per-Request and at the conceptual level it makes sense, but I haven't
seen code that makes sense (and the context for this pattern is often
web, which doesn't work for me).

If anyone has any suggestions or best practices, particularly any code
or pseudo code that I can read to get a clear understanding of the
parts involved and how they interact, I'd appreciate it.

Details about my application: From the application point of view, it's
easy for me to create boundaries for a unit of work. I basically have
a controller class that is responsible for creating/managing views in
a MVP fashion, and then handling some elementary coordination. So the
controller works as a pretty good UoW boundary; it's very feature
specific. But what I can't figure out is how the NHibernate session is
actually best managed in this scenario, how the abstractions are
handled, and how the session relates to other things that need to make
use of it (like a Repository).

I'm using StructureMap for IoC, and I'd really like to take advantage
of that. This is something that is in the greenfield arena, and in the
very beginning phases of development, and I want to make good
decisions about this design up-front.

Appreciate any help anyone can lend.

-Chris

Fabio Maulo

unread,
Aug 22, 2009, 12:53:41 PM8/22/09
to nhu...@googlegroups.com

Raul Carlomagno

unread,
Aug 22, 2009, 3:11:27 PM8/22/09
to nhusers
you can try castle activerecord too, it abstracts a little NH Sesion
artifact

Fabio Maulo

unread,
Aug 22, 2009, 3:22:31 PM8/22/09
to nhu...@googlegroups.com
2009/8/22 Raul Carlomagno <rcarl...@gmail.com>


you can try castle activerecord too, it abstracts a little NH Sesion
artifact

sure.

--
Fabio Maulo

ChrisHolmes

unread,
Aug 22, 2009, 8:20:36 PM8/22/09
to nhusers
I've looked at this blog post before I posted to this message group,
and it just doesn't make any sense to me. I don't see how to use it in
an actual application scenario. I can't tell if there are multiple
sessions, or just one session for the entire application?

What is a recommended approach to a WinForm application? One session
for the life of the WinForm app? Or multiple sessions? How long should
a session live? Who controls when a session is created and when it
dies? How does that control propagate to repositories or other lower-
level code that actually needs to make use of the session? Or do you
not even worry about abstracting the NHibernate stuff away, and just
use the ISession as a unit of work in the actual application?

I have yet to see anyone explain this clearly.

-Chris

On Aug 22, 9:53 am, Fabio Maulo <fabioma...@gmail.com> wrote:
> http://fabiomaulo.blogspot.com/2009/01/aspect-conversation-per.html<http://fabiomaulo.blogspot.com/2009/01/aspect-conversation-per.html>Start
> from the first of the serie
>
> Examplehttp://code.google.com/p/unhaddins/source/browse/#svn/trunk/Examples/...
>
> 2009/8/22 ChrisHolmes <cb.hol...@gmail.com>

ChrisHolmes

unread,
Aug 22, 2009, 8:23:11 PM8/22/09
to nhusers
I am not interested in Castle ActiveRecord.

I'm interested in actually learning how to accomplish my goals. I'll
write my own bits to accomplish my tasks, but I need to understand how
and why things work, and how they should be done.

I don't have an understanding of HOW to actually manage the NHibernate
ISession in a WinForm application. No one cares to explain that. I
don't understand how, when I do have an ISession managed, how I use
that in something like a Repository, which is code that will live much
closer to the DB than a higher level WinForm controller. No one cares
to explain that either.

I've read a whole lot of theoretical stuff about session-per-
conversation, but no one actually takes any time to describe the how
and way and actually show the usage. It's very discouraging.

-Chris

José Romaniello

unread,
Aug 22, 2009, 8:32:51 PM8/22/09
to nhu...@googlegroups.com
2009/8/22 ChrisHolmes <cb.h...@gmail.com>

I've looked at this blog post before I posted to this message group,
and it just doesn't make any sense to me. I don't see how to use it in
an actual application scenario. I can't tell if there are multiple
sessions, or just one session for the entire application?

Why don't make any sense to you? 

 


What is a recommended approach to a WinForm application? One session
for the life of the WinForm app?

This is not recommended pattern. (time bomb)

 
Or multiple sessions? How long should
a session live?
it depends.
 
Who controls when a session is created and when it
dies?

depends uppon the conversation. have a look to the attributes.

 
How does that control propagate to repositories or other lower-
level code that actually needs to make use of the session? Or do you
not even worry about abstracting the NHibernate stuff away, and just
use the ISession as a unit of work in the actual application?

My concrete implementation of repositories have a dependency to sessionfactoy. 
Inside I use SessionFactory.GetCurrentSession().


look the winform example at unhaddins.

José Romaniello

unread,
Aug 22, 2009, 8:36:12 PM8/22/09
to nhu...@googlegroups.com
I'm working on a WPF example, but this post could help you too:


2009/8/22 José Romaniello <jfroma...@gmail.com>

Belvasis

unread,
Aug 22, 2009, 9:38:41 PM8/22/09
to nhu...@googlegroups.com
Hm, I think the first part of the blog describes the how and why of the pattern well enough

http://fabiomaulo.blogspot.com/2008/12/conversation-per-business-transaction.html

But I think, it will not fit in every scenario of a winform application or maybe I didn't understand all of it :-).
The problem i have is, for example if it comes to lazy loading. Simply think of two views, one shows
a list of data and the other one details for the selected entity, with lazy loaded attributes. The two
views are independed of each other and part of independend use cases. But while both usecases may
be instantiated from one parent usecase they may also be instantiated standalone. So the lifetime of
a specific repository may span several usecases or just one, if you want to avoid multible queries for the
same entity. My approach to this is to use a  PersistenceContext. Every usecase may instantiate it's own
PersistenceContext or may use the PersistenceContext, provided by the CallingContext. So i'm able to simply
control the lifetime of the  Repository. Since the views are controlled by the usecase they simply use the
Repository provided by the PersistenceContext. So, if the user wants to edit an entity from the list, this
starts a new usecase with a modal view and an own PersistenceContext. If this transaction fails, it has
nothing to do with the already displayed entity. If is is commited succesfully, i just have to refresh the entity in
the "main" context. I don't know if this is a good approach, but it works really nice for me. And since
informations about NH and WinForms are really rare and even the NHiA book doesn' really tell
something about it, i'll stick to it :-)





2009/8/23 ChrisHolmes <cb.h...@gmail.com>

José Romaniello

unread,
Aug 22, 2009, 9:41:19 PM8/22/09
to nhu...@googlegroups.com
You call "theoretical stuff" to a working example:

Fabio Maulo says:

>Example


Fabio's post are full of samples too.

Are you looking for a more personal explanation?

2009/8/22 ChrisHolmes <cb.h...@gmail.com>

Stefan Nobis

unread,
Aug 23, 2009, 2:17:42 AM8/23/09
to nhu...@googlegroups.com
ChrisHolmes <cb.h...@gmail.com> writes:

> I have yet to see anyone explain this clearly.

Ok, I'll try to give at least some guideline.

First of all: The most important thing to remember is that an ISession
is really unstable and unreliable (according to the book 'Exceptional
C++' of Herb Sutter ISession even breaks the fundamental level of
guarantee). Therefore is should be used only for short periods of time
and be thrown away as fast as possible, because any NHibernate
exception and each rollback immediatley invalidates the session
object.

On the other hand there is lazy loading and this works only as long as
the session is still open. But I think, in many cases it should be
considered bad practise to just load a root entity and rely on
NHibernates lazy loading mechanism to pull all dependent entities into
memory. This pattern is a real performance killer.

IMHO a much better idea is to think of lazy loading as a way of being
able to ignore some data if they don't matter in a given use case. So
for each use case you should always eagerly load all data you will
need and therefore there is no problem in early closing the session.

That's the motivation for all these rather complex patterns like
Session per Business Transaction, Persistence Context, etc.

If you are all new to this, don't try to invent everything from
scratch in your first application. Either use the patterns and
libraries already mentioned or, if you want to really understand and
develop everything yourself, start simple. A rather simple approach
may be to define a service layer (e.g. just a single static class)
that has a public API derived from use cases and only in this layer
ISession objects and a session factory is allowed. Then in each public
method a fresh session is opened, data fetched, maybe some kind of
post-processing/conversion/transformation is done, and before
returning the result the session will be closed. This is the basic
idea of session per business transaction (or per use case).

For applications that are not too complex this might suffice, in more
complex scenarios patterns like the mentioned persistence context
might be needed.

Hope, this helps a little bit.

--
Until the next mail...,
Stefan.

Fabio Maulo

unread,
Aug 23, 2009, 9:27:29 AM8/23/09
to nhu...@googlegroups.com
That impl. allow what you are describing.
A winForm, for use, should work using MVP.
The P (or its variation VM for example) may work with its M or may share an M from a "parent" usecase.

The M does not know if the persistence is implemented using NH or ADO.NET as the DAO/Repository impl. does not know which is the sessionManager (DAOs/Repository implementation does know only its dependency on ISessionFactory).

If you set the EndMode to End by default, that pattern work as session-per-request (close the session after the execution of each method).
So far Models with CpBT are used in winForm, WPF, MonoRail, ASP.MVC and WCF.

If the pattern does not work for you, perhaps, you can propose something different..
Chris Holmes said:
"I've Googled this to death and I still can't find anything that makes sense and I haven't found any actual code that I can read and make sense out of".

Well now he have an example that make sense. If he want use it or not is another matter.

--
Fabio Maulo

Fabio Maulo

unread,
Aug 23, 2009, 9:36:04 AM8/23/09
to nhu...@googlegroups.com
Belvasis, have you post an example some where ?
If you want post your examples in NH-Forge let me know.
Thanks.
--
Fabio Maulo

Jim Tanner

unread,
Aug 23, 2009, 11:36:16 AM8/23/09
to nhusers
I am also interested in the subject.
Is there any MVP or MVVM open source framework that can handle
winforms ?


On 23 août, 15:36, Fabio Maulo <fabioma...@gmail.com> wrote:
> Belvasis, have you post an example some where ?If you want post your
> examples in NH-Forge let me know.
> Thanks.
>
> 2009/8/22 Belvasis <belvasis...@googlemail.com>
>
>
>
> > Hm, I think the first part of the blog describes the how and why of the
> > pattern well enough
>
> >http://fabiomaulo.blogspot.com/2008/12/conversation-per-business-tran...
> > 2009/8/23 ChrisHolmes <cb.hol...@gmail.com>

Tuna Toksoz

unread,
Aug 23, 2009, 11:41:55 AM8/23/09
to nhu...@googlegroups.com
Caliburn?

ChrisHolmes

unread,
Aug 23, 2009, 11:43:52 AM8/23/09
to nhusers
Blevasis,

This is a great explanation of the way you're doing it. But again, I
don't understand it. Specifically, I don't understand the details of
how it is implemented.

Example: The Calling Context and the Persistence Context. You say:

> "Every
> usecase may instantiate it's own
> PersistenceContext or may use the PersistenceContext, provided by the
> CallingContext."

How is the Calling Context provided to the use case? How does the use
case receive that dependency? Constructor injected? How does your IoC
get configured to make that happen? Are you having to mess with your
IoC container all the time, re-injecting contexts so lower level use
cases get the right context? This is where I'm confused on all this
stuff - implementation.

I can't see how to implement any of this in a clean way that makes
sense.

-Chris

On Aug 22, 6:38 pm, Belvasis <belvasis...@googlemail.com> wrote:
> Hm, I think the first part of the blog describes the how and why of the
> pattern well enough
>
> http://fabiomaulo.blogspot.com/2008/12/conversation-per-business-tran...
> 2009/8/23 ChrisHolmes <cb.hol...@gmail.com>

ChrisHolmes

unread,
Aug 23, 2009, 11:47:06 AM8/23/09
to nhusers


On Aug 22, 5:32 pm, José Romaniello <jfromanie...@gmail.com> wrote:
> 2009/8/22 ChrisHolmes <cb.hol...@gmail.com>
>
>

> Why don't make any sense to you?

Implementation. How things get wired together. Who calls who. How do
dependencies get resolved. What does an actual unit of work look like
in code at a high level.


>
> > Or multiple sessions? How long should
> > a session live?
>
> it depends.

I know it depends. But it's like no one wants to answer that question
with even a simple example.

>
> > Who controls when a session is created and when it
> > dies?
>
> depends uppon the conversation. have a look to the attributes.

It depends. Another way of saying, "I'm not going to answer".


> look the winform example at unhaddins.

I guess I'll have to. It appears to be the only thing that has any
answers.

-Chris

ChrisHolmes

unread,
Aug 23, 2009, 11:50:34 AM8/23/09
to nhusers

>
> If you are all new to this, don't try to invent everything from
> scratch in your first application. Either use the patterns and
> libraries already mentioned or, if you want to really understand and
> develop everything yourself, start simple.

Yes! Because understanding is the most important thing! I am not going
to just grab other people's bits and implementations without
understanding them and start using them. That is not how I grow as a
developer. I have to understand it. And that means I need information,
and details. I need more information.

> A rather simple approach
> may be to define a service layer (e.g. just a single static class)
> that has a public API derived from use cases

"derived from use cases " - That's the first thing I've read that
makes sense. Thank you.

> and only in this layer
> ISession objects and a session factory is allowed. Then in each public
> method a fresh session is opened, data fetched, maybe some kind of
> post-processing/conversion/transformation is done, and before
> returning the result the session will be closed. This is the basic
> idea of session per business transaction (or per use case).
>
> For applications that are not too complex this might suffice, in more
> complex scenarios patterns like the mentioned persistence context
> might be needed.
>
> Hope, this helps a little bit.

A little bit. Thank you Stefan!

-Chris

Carlos cubas

unread,
Aug 23, 2009, 12:13:19 PM8/23/09
to nhu...@googlegroups.com
I think foremost, you should tone down your demanding attitude. Everybody is willing to help you just not with you demanding such attention.

Again, you should really take a close look at the unhaddins impl, run the samples, etc.  I was in the same boat as you some time ago.  And managed to figure it out.  It can't be that hard can it?

-Carlos
 
Practice makes perfect, but if no one is perfect, why practice?




> Date: Sun, 23 Aug 2009 08:50:34 -0700
> Subject: [nhusers] Re: How to handle Session in WinForm project?
> From: cb.h...@gmail.com
> To: nhu...@googlegroups.com

Fabio Maulo

unread,
Aug 23, 2009, 12:21:28 PM8/23/09
to nhu...@googlegroups.com
Carlos you know.... demand is the more easy thing to do... the hard one is think or share something.

2009/8/23 Carlos cubas <ven...@hotmail.com>



--
Fabio Maulo

Jim Tanner

unread,
Aug 23, 2009, 12:27:45 PM8/23/09
to nhusers
@Tuna : I don't find any mention of winform around caliburn but i may
be mistaken. Are u sure they mix well before i digg further ?

@Carlos : By any chance did u try the winform sample inside NhContrib
(not unhaddins)? Do u remember getting it work or was it broken ?

@ChrisHolmes and Belvasis : Are you writting / have you written a
winform nh framework from scratch or can u point me to an existing
framework ?

@Every one who might be interrested : This article deals with a way to
handle lazy loading in winforms.
http://www.codeproject.com/KB/cs/NHibernateLazyInitializer.aspx



On 23 août, 18:13, Carlos cubas <veno...@hotmail.com> wrote:
> I think foremost, you should tone down your demanding attitude. Everybody is willing to help you just not with you demanding such attention.
>
> Again, you should really take a close look at the unhaddins impl, run the samples, etc.  I was in the same boat as you some time ago.  And managed to figure it out.  It can't be that hard can it?
>
> -Carlos
>
> Practice makes perfect, but if no one is perfect, why practice?
>
> > Date: Sun, 23 Aug 2009 08:50:34 -0700
> > Subject: [nhusers] Re: How to handle Session in WinForm project?
> > From: cb.hol...@gmail.com

Tuna Toksoz

unread,
Aug 23, 2009, 12:37:31 PM8/23/09
to nhu...@googlegroups.com
No I am not sure, I may be wrong.

Belvasis

unread,
Aug 23, 2009, 1:55:15 PM8/23/09
to nhu...@googlegroups.com
Hm i tried to write a winform framework (mostly) independend of NH. My attemp was that the hole session thing
is transparent for the developer, so that all one has to know about NH is the ICriteria interface. So i have
a IPersistenceService that is resolved by IoC. The Service has a method OpenSession wich returns an
IPersistenceSession (no NH Session). The IPersistenceSession holds an IPersistenceContext wich in case
of NH usage manages the ISession for the IPersistenceSession. So every UseCase works with such a
IPersistenceSession and resolves IRepository<T> instances from it. Every IRepository<T> instance is valid
only within this IPersistenceSession/IPersistenceContext. If one resolves an IRepository<T> directly from
the IoC container, it uses it's owen independend IPersistenceSession.
The Winform stuff is build like MVC. The views are simply usercontrols implementing an IContentView interface.
Views are managed by the controller wich is a IUseCase instance and live in a main ContenView ( IWorkbench).
The Workbench provides the CallingContext to the IUseCase. The IUseCase builds an ExecutionContext from
this CallingContext or retrieves one if it is called by another IUseCase. The ExecutionContext simply contains
a IWorkbench reference and a reference to the calling IUseCase. Since the IUseCase has also a reference
to an IPersistenceSession it can simply be used by child UseCase's. The workbench itself is build from an
IUseCaseSchema wich contains a tree of IUseCaseItems where every item may reference a IUseCaseDefinition.
The IUseCaseDefinition can be used to build and execute the IUseCase, wich is done by the IUseCaseRepository,
since there is some proxy stuff involved to manage permission and other dependencies.
So in the end it looks like this:

IWorkbench
   ---> IUseCaseSchema
      ---> IUseCaseItem
         ---> Button/Treenode, Menue etc.
          ---> Click (:-))
           ---> IUseCaseRepository.doBuildUseCase(Definition,CallingContext)
             ---> IUseCase.doExecute
               ---> IPersistenceService.OpenSession
                 ---> do things...or
                   ---> create IContentView
                     ---> ContentView.PersistenceSession = IUseCase.PersistenceSession
                       ---> IWorkbench.doAddView(ContentView)
                         ---> ContentView...Button...is again an IUseCaseItem with IUseCaseDefinition... Click...
                          ---> IUseCase.doExecuteChildUseCase(Definition, ExecutionContext)...ExecutionContext.Entity = Currently selected entity
                            ---> this.PersistenceSession = ExecutionContext.PersistenceSession
                              ---> work with the ExecutionContext.Entity
                           - OR -
                            ---> this.PersistenceSession = IPersistenceService.OpenSession
                              ---> reload the Entity within the newly created IPersistenceSession
                                  ( IPersistenceSession.getRepository<T>().getObject(ExecutionContext.Entity.ID)
                            ---> do soemthing usefull
                          ---> close view....IWorkbench.doRemoveView(ContentView)
                          ---> IUseCase.doStop
          ---> Click another Item
            ---> IUseCase.doPause
            ---> build and execute another IUseCase

So i don't know if this is all a little naive and therefore i didn't post anything about it. It works well, but i will
rethink the pattern from Fabio if or how it fits in all this. I'm just a little carefully :-)

2009/8/23 Jim Tanner <dob...@gmail.com>

Fabio Maulo

unread,
Aug 23, 2009, 2:38:24 PM8/23/09
to nhu...@googlegroups.com
Belvasis,
have a look to the video at the bottom of the post
--
Fabio Maulo

Fabio Maulo

unread,
Aug 23, 2009, 2:45:11 PM8/23/09
to nhu...@googlegroups.com
did you see the video ?
Now have a look on how look the IRepository and the Model (the UseCase)

All is working with MVVM databing, Observable collection, error providers and so on but....
but entities look as:



--
Fabio Maulo

Belvasis

unread,
Aug 23, 2009, 4:13:02 PM8/23/09
to nhu...@googlegroups.com
I know this blog and the video and it is fine. As I said I will rethink the CpBT. Maybe the name "UseCase" from
my last post is a little misleading. The "UseCase" is more a "ICommand" compared to the example. It is just
decoupled from the ViewModel to simplify configuration, permission control, dependency checking etc. As part of
the infrastructure of the app it allows to extend the application in a simple way, without touching any existing code.
The "real" Model's and Repositories are looking  similiar to the one from the example. In the end I think we come
to the same result, but as i read it now, i think the CpBT approach is more elegant and robust. Thanks 

2009/8/23 Fabio Maulo <fabio...@gmail.com>

Fabio Maulo

unread,
Aug 23, 2009, 4:28:33 PM8/23/09
to nhu...@googlegroups.com
Belvasis,
If you need a place where share a post about another solution than CpBT let me know. You can post your solution and code in NH-Forge, really.
More than one option is always welcome and in general people sharing his code and his experience are welcome in NH-Forge.
--
Fabio Maulo

Belvasis

unread,
Aug 23, 2009, 7:05:57 PM8/23/09
to nhu...@googlegroups.com
Yes thats true and i will do it, if i'm finished with it :-) But in general would n't it be a good idea to
have a place at NHForge where new users can quickly find informations for specific themes?
The current Patterns & Practices section is a little short. In the end some sort of link collection
would be enough, i think. Kind of

NHibernate and Winforms/WPF
    - link to CpBT
    - lint to  WPF example

NHibernate and ASP.MVC
    - ...

NHibernate extended
    - link to Less then "Few" is GoF

Fun
    - A real battle  ...nice :-)
etc.
Sure, one has to maintain it but it would save a lot of time googling around looking if there are new
blog entries at various sites etc.

Fabio Maulo

unread,
Aug 23, 2009, 10:23:27 PM8/23/09
to nhu...@googlegroups.com
well very well and good proposals.

We need an help in NH-Forge you all are candidate to help... this is the proposal of www.nhforge.org
Perhaps we should re-new the initial spirit of the site FOR NHibernate community
--
Fabio Maulo

Wojciech Wieronski

unread,
Aug 23, 2009, 10:23:31 PM8/23/09
to nhusers
Chris I feel your pain. I had the same issues when starting with NH
and a winform app. Here is my experience. Hope it helps.

A simple Repo.

public class HealthcareProfessionalRepository :
IHealthcareProfessionalRepository
{

ISessionFactory _sessionFactory;

public HealthcareProfessionalRepository(ISessionFactory
sessionFactory)
{
_sessionFactory = sessionFactory;
}

private ISession CurrentSession
{
get { return _sessionFactory.GetCurrentSession(); }
}

public HealthcareProfessional GetById(int hcpId)
{
return CurrentSession.Get<HealthcareProfessional>(hcpId);
}


}


As you can see the repo interacts with the Session via a call to the
SessionFactory's GetCurrentSession func.
Now all this mumbo jumbo about SessionContext is really how the
SessionFactory knows which Session instance to return
when GetCurrentSession is called.

There are several different Implementations:

*

NHibernate.Context.ManagedWebSessionContext - current sessions
are tracked by HttpContext. However, you are responsible to bind and
unbind an ISession instance with static methods on this class, it
never opens, flushes, or closes an ISession itself.
*

NHibernate.Context.CallSessionContext - current sessions are
tracked by CallContext. You are responsible to bind and unbind an
ISession instance with static methods of class CurrentSessionContext .
*

NHibernate.Context.ThreadStaticSessionContext - current session
is stored in a thread-static variable. This context only supports one
session factory. You are responsible to bind and unbind an ISession
instance with static methods of class CurrentSessionContext.
*

NHibernate.Context.WebSessionContext - analogous to
ManagedWebSessionContext above, stores the current session in
HttpContext. You are responsible to bind and unbind an ISession
instance with static methods of class CurrentSessionContext.

Checkout ("http://knol.google.com/k/fabio-maulo/nhibernate-
chapter-2/1nr4enxv3dpeq/6#") for more details.


I use the NHibernate.Context.ThreadStaticSessionContext for my winform
app.
In the hibernate.cfg.xml file.
Add this config line: <property
name="current_session_context_class">NHibernate.Context.ThreadStaticSessionContext,
NHibernate</property>


Now how to use it.....


In my use case I have a winform with several tabs. When a user enters
a tab the data will be lazily loaded (this is great because not all
the tabs
are always visited, so data is only loaded when needed.)


in psuedo code

Form Load
{
_session = sessionFactory.OpenSession();
NHibernate.Context.CurrentSessionContext.Bind(_session)
_hcp = HCPRepo.GetById(1234);
LoadUI()
_session.Disconnect();
NHibernate.Context.CurrentSessionContext.Unbind(SessionFactory)
}

For the most part, this should be self explanitory but I will point
out the following: the Bind, Unbind and the Disconnect.

The Bind takes the session as an argument and bascially tells the
SessionFactory, hey when GetCurrentSession is called, serve up this
session.
And it will work from every Repo or whatever DAO makes use of the
GetCurrentSession call from the SessionFactory.

The UnBind says, OK im done working with the session for now (in a
nutshell).

The only time you need bind and unbind is when your making calls to
your DAOs and they need a reference to the current session (your UoW)
otherwise they would not have a reference to your session.

Lastly, the disconnect is used so that your not hogging up ADO.NET
connections. If you were to close the session you would have to open
a new one,
reattach it via locking, updating, etc.....it becomes a nightmare and
is not good practice anyway. When you need to load stuff you just,
reconnect, load and then disconnect.


Tab 2 Enter
{
if (!loadedBefore)
{
_session.Reconnect();
LoadGridwithStuffFromHCPBlahBlah();
_session.Disconnect();
}
}

Form Close
{
_session.Close();
}

Close the session, its a done deal.


One last thing, your DAOs (Repos etc.) should take a sessionFactory as
a dependency and your IOC Container can inject it.


Hope this helps.

ChrisHolmes

unread,
Aug 23, 2009, 10:38:55 PM8/23/09
to nhusers


> Again, you should really take a close look at the unhaddins impl, run the samples, etc.  I was in the same boat as you some time ago.  And managed to figure it out.  It can't be that hard can it?

I am definitely going to take a look at the implementation. It's just
time consuming; downloading svn, downloading the code, configuring it
against a DB (making an assumption here), compiling, running,
analyzing the patterns and usage... It's something I have to wait to
do until I get back to work on Monday. I was hoping for a conversation
that would spark ideas on my brain, because my brain is on all
weekend... It doesn't have to wait for Monday.

> I think foremost, you should tone down your demanding attitude. Everybody is willing to help you just not with you demanding such attention.

I understand that. I appreciate the sentiment. I know I am demanding.
I apologize.

I am trying to learn and figure things out, and this has been
frustrating because the solutions haven't come to me quickly and
easily like they usually do.

This is a subject matter I've spent a lot of time thinking about
(NHibernate in WinForm), researching and trying to figure out. I've
put considerable thought into this for a long time now, and it's
probably been the most aggravating subject I've dealt with as a
developer. It's like a puzzle, only I can only see a few of the
pieces, and I can't see how any of the pieces connect together. There
are people with a lot of knowledge and experience who can look at the
puzzle, and they see many more pieces than I do - maybe the whole
puzzle and what it looks like when it's put together. But when they
blog about it, they leave out the interesting pieces. So I am left
looking at an incomplete puzzle.

I just want to get a clear picture so I can solve problems. Nhibernate
is, in my opinion, the best OR/M available. I've used it in another
project, but I am sure I used it incorrectly (although it works). I've
had to build DAL's with ADO.NET before, and I've used OR/M's like
LLBLGenPro and Wilson, and I just love the simplicity of NHibernate
(especially with the Fluent NHibernate bits for configuration). I have
a chance on a new project to make a pitch to use NHibernate, but I
have to have a way to make it work correctly in WinForms. If I can't
figure it out soon, I won't be able to make a legitimate pitch to use
it, and we'll probably end up using something else that I'll be less
than pleased with.

I do appreciate everyone's feedback and help.

-Chris


ChrisHolmes

unread,
Aug 23, 2009, 10:48:03 PM8/23/09
to nhusers

> @ChrisHolmes and Belvasis : Are you writting / have you written a
> winform nh framework from scratch or can u point me to an existing
> framework ?

I am in the process of evaluating potential ways to use NHibernate in
a WinForm application. I haven't written anything yet, just been
thinking, reading, researching and trying to generate a pattern in my
head that makes sense. I want to do something that is simple for the
developer; something that abstracts the session management away from
the developer and the application so that the application is not aware
of NHibernate.

Right now my thinking is that the whole thing rests on the concept of
a Unit of Work. And a Unit of Work is something that can hold a
context, which then could be made available to Repositories. UoW
boundaries in WinForms can sometimes be difficult to define, but I
think if one builds their application around the idea of a Unit of
Work to begin with, then it might help shape those boundaries a bit
better.

But that's just what I am thinking about now. When I get a chance to
look at Fabio's implementation on Monday, my thoughts may change.

-Chris

ChrisHolmes

unread,
Aug 23, 2009, 10:49:15 PM8/23/09
to nhusers
Belvasis,

Thank you for the detailed post sir! This is so very good!

I do not know if this is something I will use, but it at least gives
me a very clear implementation pattern to analyze. It gives me a lot
to think about, which is good!

Thank you sir!

-Chris
> 2009/8/23 Jim Tanner <dobr...@gmail.com>

ChrisHolmes

unread,
Aug 24, 2009, 11:52:52 AM8/24/09
to nhusers

Wojciech,

Thank you sir. This is incredibly helpful. I had no idea this
capability for contextual sessions existed in NHibernate. I believe
this is going to help me tremendously.

Awesome post Wojciech.

-Chris

On Aug 23, 7:23 pm, Wojciech Wieronski <wojciech.wieron...@gmail.com>
wrote:

Fabio Maulo

unread,
Aug 24, 2009, 11:55:57 AM8/24/09
to nhu...@googlegroups.com
2009/8/24 ChrisHolmes <cb.h...@gmail.com>


 This is incredibly helpful. I had no idea this
capability for contextual sessions existed in NHibernate. 

And this mean you haven't read all previous mails and links.

--
Fabio Maulo

Stefan Nobis

unread,
Aug 24, 2009, 2:03:32 PM8/24/09
to nhu...@googlegroups.com
Jim Tanner <dob...@gmail.com> writes:

> @Every one who might be interrested : This article deals with a way to
> handle lazy loading in winforms.
> http://www.codeproject.com/KB/cs/NHibernateLazyInitializer.aspx

I don't think this is a good idea, because it may lead to quite bad
performance. A much better approach would be to tailor your HQLs (or
criteria queries) to each use case and select exactly the data you
need to touch explicitly (in many cases this is even possible in one
single HQL, with the help of join fetch and maybe
DistinceRootTransformer, and thus in one single round-trip to the DB,
instead of dozens or even hundreds of round-trips in case of the
generic NNhibernateLazyInitializer).

ChrisHolmes

unread,
Aug 24, 2009, 3:13:39 PM8/24/09
to nhusers
And how exactly is that attitude helping me?

Everyone has been pretty kind here - except you.

-Chris

On Aug 24, 8:55 am, Fabio Maulo <fabioma...@gmail.com> wrote:
> 2009/8/24 ChrisHolmes <cb.hol...@gmail.com>

José Romaniello

unread,
Aug 24, 2009, 3:37:19 PM8/24/09
to nhu...@googlegroups.com
The attitude that will help you is the reader attitude
No one has enough time to write something twice.
You should be reading the former links and then answer concrete questions. 
You say that you don't have enough time to execute the samples and configure it. But you have enough time to complain that nobody want to help you.



2009/8/24 ChrisHolmes <cb.h...@gmail.com>

Jim Tanner

unread,
Aug 25, 2009, 4:19:55 PM8/25/09
to nhusers
@Stefan
http://www.codeproject.com/KB/cs/NHibernateLazyInitializer.aspx
"A much better approach would be to tailor your HQLs (or
criteria queries) to each use case and select exactly the data you
need to touch explicitly"

Yeah i m also convinced that loading stricly not any more column or
row than necessary, is mandatory 90 % of the time.

The benefit i m expecting with lazy loading is a programmatic comfort
where i know i wont load much data whatever happens. I have hard time
finding it in winforms because our application uses one session for
every call, grab the data, then close it. So i m outside of any open
session most of the time. Any trick would be good for me, but i admit
i did not try this yet.
You think it s not even worth the try ?

@Fabio
Even if your articles are very clear and the samples in nhaddins are
very good, reading them was not enough for me to understand them.

And it took me a lots of efforts to understand where is the CpBt in
the samples.
Now big part will be to find a way to fit it in our application.

I probably did not have enough background and practice to digest them,
but i guess lots of users are more or less in the same case.

Thanks anyway.


On 24 août, 20:03, Stefan Nobis <stefan...@snobis.de> wrote:

Fabio Maulo

unread,
Aug 25, 2009, 4:51:15 PM8/25/09
to nhu...@googlegroups.com
2009/8/25 Jim Tanner <dob...@gmail.com>

@Fabio
Even if your articles are very clear and the samples in nhaddins are
very good, reading them was not enough for me to understand them.

And it took me a lots of efforts to understand where is the CpBt in
the samples.
 
Really thanks for this compliment; if you can't find where is CpBT mean that one of the main target was archived.
Implement CpBT as a NO INTRUSIVE solution.
José is showing this fact in his post:

btw if you want you can read this two post and you will see where is CpBT


The first post shows a "manual" CpBT usage.
The second is how we are actually using it.

Thanks again.

Fabio Maulo

ChrisHolmes

unread,
Aug 28, 2009, 11:08:17 AM8/28/09
to nhusers
Follow up, in case anyone else stumbles on this thread:

I managed to get something simple working and am fairly happy with the
result, but would like to vet the idea against the community to make
sure I'm not doing something horribly wrong.

What I ended up doing was writing an IUnitOfWork interface that
essentially becomes a wrapper around the NHibernate ISession. The
interface basically looks like this:

public interface IUnitOfWork
{
void Start();
void Finish();
void Rollback();
void Commit();
}

Obvious stuff, yeah?

Starting the UnitOfWork initiates the process of getting an ISession
from the SessionFactory and binding it to the CurrentContext.
Finishing a UnitOfWork unbinds.

Using it in a WinForms application then becomes a simple matter of
designing your use cases around the concept of a UnitOfWork. Sometimes
a window's Presenter is the boundary for a UnitOfWork, and you can
start and finish the UoW when the window opens/closes. Sometimes the
boundary is a bit bigger, so for those cases I use a "controller"
class that manages the use case, handling creation of views, etc., and
acting as the boundary for the UoW.

It's a more explicit approach, certainly, that using AoP to handle the
session management, but it is completely abstracted from my
application, which I like. And the big thing is that it works.

If I'm doing anything wrong here, please let me know.

-Chris

Germán Schuager

unread,
Aug 28, 2009, 12:19:11 PM8/28/09
to nhu...@googlegroups.com
I like that approach too.
One thing to keep in mind is that if your application allows simultaneous use-cases (MDI or multi-tabbed UI) you need to care about how are you isolating each unit of work to its corresponding use case.

Fabio Maulo

unread,
Aug 28, 2009, 5:24:08 PM8/28/09
to nhu...@googlegroups.com
And he need to manage transactions too...
I hoping he don't want begin a transaction at UoW start.
After that I would see the code where the UoW is used...

2009/8/28 Germán Schuager <gsch...@gmail.com>



--
Fabio Maulo

ChrisHolmes

unread,
Aug 31, 2009, 3:57:41 PM8/31/09
to nhusers
What would be the best practice for managing transactions Fabio?

Initially, I had my Repositories handling their own transactions. Like
so:

*********************************************************
public class DeviceRepository : IRepository<Device>
{
private IDataSource _db;

public DeviceRepository(IDataSource dataSource)
{
_db = dataSource;
}

public Device Find(int id)
{
Device item = null;
using (ISession session = _db.GetCurrentSession())
{
ITransaction tx = session.BeginTransaction();
try
{
IQuery query = session.CreateQuery("select d from
Device as d where d.Id = :Id");
query.SetInt32("Id", id);
item = query.UniqueResult<Device>();
}
catch (Exception e)
{
ExceptionHandler.HandleException(e);
}
finally
{
tx.Commit();
}
}

return item;
}
*********************************************************

But then after I had the UnitOfWork interface, I thought that made a
better boundary. You are saying no. So what is the recommended
approach? And what are the drawbacks to starting the transaction with
the UoW?

-Chris

On Aug 28, 2:24 pm, Fabio Maulo <fabioma...@gmail.com> wrote:
> And he need to manage transactions too...I hoping he don't want begin
> a transaction at UoW start.
> After that I would see the code where the UoW is used...
>
> 2009/8/28 Germán Schuager <gschua...@gmail.com>
>
>
>
> > I like that approach too.
> > One thing to keep in mind is that if your application allows simultaneous
> > use-cases (MDI or multi-tabbed UI) you need to care about how are you
> > isolating each unit of work to its corresponding use case.
>

Fabio Maulo

unread,
Aug 31, 2009, 11:12:24 PM8/31/09
to nhu...@googlegroups.com
the answer is too long.
you will discover it by your self when you will need two "save" in the same transaction or/and when you will have 2 opened forms needing 2 different business transactions. 

2009/8/31 ChrisHolmes <cb.h...@gmail.com>



--
Fabio Maulo
Reply all
Reply to author
Forward
0 new messages