I've been implementing Linq support for IStatelessSession, and it's
going fairly smoothly, except for one issue. I need to call the same
query creation method on both the ISession and IStatelessSession. In
my previous work, I also realized that I might need to access a
session to get information about the registered entities (though
that's not being used at this moment). It made me wonder about the
relationship between ISession and IStatelessSession. There are
clearly many methods that have the same signature and purpose, but on
the other hand, using IStatelessSession in comparison to ISession is
very different and one would usually want to be well aware of which
one you're working with.
To solve this problem, I've considered the following possibilties:
1. Provide a common base interface for the two session types that
provides common methods when appropriate. (Ex. IGenericSession)
2. Create duplicate versions of every method / object that requires
access to a "generic" session.
3. Instead of a common base interface for sessions, just have one for
the query factories, as in NH-2211.
4. Create a wrapper object that accepts either an ISession or
IStatelessSession and delegates to the common methods.
In the interest of simplicity, I'd like to go with the first approach
for the Linq stateless session support. I realize this is a
significant change though, so I'm happy to modify that portion if need
be.
Here are my thoughts on the various approaches.
1. It looks like a good idea to trend towards a common base interface
for the sessions. Though they differ, there are many common
operations. When considering how to utilize the ISession and
IStatelessSession in my own applications, I also find it preferable to
have common methods on a common interface in NHibernate. The
documentation sometimes differs for the two session implementations,
but it could be combined with separate notes for the two session
types. In other cases, it seems like the interfaces could simply be
made more like each other with no problems. Since I have seen the
need for common session operations multiple times, I believe this is
the best choice.
2. I quickly discarded this approach since it was getting unruly in
even my simple test.
3. This is okay, but it ignores the fact that common non-factory
methods are needed in some scenarios.
4. I'd be okay with doing this if there were good reasons to not
modify the interfaces, but it's certainly not the simpler approach.
It adds additional overhead in creating the wrapper object and
maintaining a reference to it instead of the original session.
Thoughts?
Patrick