Why not just embed ISession in your repositories instead of ISessionFactory ?
Here is the similar code that I use with Autofac, another IoC container:
containerBuilder .Register(c => NHibernateContext.GetSessionFactory().OpenSession()) .As<ISession>() .InstancePerLifetimeScope();
where NHibernateContext is my one and only static class that configures NHibernate and holds on to the ISessionFactory ISessionFactory .
So my repository / search object is requesting a session:
public MyRepository(ISession session) { this.session = session; }
Then my presenter / view model / supervisory controller / whatever Heck-We're-Call-It-This-Month just gets a repository or search object:
public MyPresenter(IWhateverRepository repository) {
For Windsor, I think (I am not very familiar with its API, you may have to configure it, but it should give you an idea), it will be something like
container.Register( Component.For<ISession> .UsingFactoryMethod( x => x.Resolve<ISessionFactory>().OpenSession()) .LifeStyle.Transient);
That is, you tell the container: "When someone asks for ISession, run this little delegate, which receives an ISessionFactory and opens a session, then give them an instance of ISession .
But who closes the ISession ? It is up to you: you could have the repository explicitly close ISession in your own Dispose() method. Or you can rely on your container for closure and disposal; in Autofac, I do this with ILifetimeScope and InstancePerLifetimeScope() ; in Windsor, I believe you need to look for nested containers, so when you install a child container, all the components that it created are also located.
In my experience, this usually means that the container seeps into at least the βmain formβ of my application: when it's time to create the form, it creates a new container / nested container lifetime and shows the form. But nothing below this level knows about the container; it's just throwing a lasso around a set of components and saying "get rid of all these cases when the form is closed."
(This is to prevent the use of just one big ISession beep on most applications. This works well in ASP.NET, one session per request, but in Windows Forms, as you noticed, it looks like a ticking time bomb for exceptions of obsolete objects. It is better for each "unit of work" (usually for each form or service) to have its own ISession .)
You can also create your repositories in such a way that each method requires passing ISession , but it seems like it is tedious.
Hope this gives you some ideas. Good luck