views:

58

answers:

2

Hi guys,

I am using Wcf in Sharp Architecture. I have configured my project following northwind sample using WcfSessionStorage etc. I have a method in the wcf service that gets a list of business object using Repository<>.GetAll(). I am testing the service method using WcfTestClient. When the method is called the very first time, everything works fine. However on the subsequent call, I get the following exception on the Repository<>.GetAll() method

[System.ObjectDisposedException]
Session is closed!
Object name: 'ISession'

It seems like the NHibernate session gets disposed after each call. I have got around this problem by decorating my service with the following attribute

[ServiceBehavior( InstanceContextMode = InstanceContextMode.PerCall )]
public class WcfService : IWcfService
{
}

However this means, an instance of the service will be created on each call that in turn will create a new nhibernate session etc. In my scenario there is no need of creating a new service instance per call and I think its an expensive process and not the right solution. I would like to know what is the best practice in my scenario and how to get this thing work with creating a new service instace per call.

Thanks Nabeel

+1  A: 

The easiest way is to create a new instance every time and it's not an expensive process, because creating a new object in .NET is like 0.00000000000000001 second (I read that on Ayande's blog or somewhere).

I use Autofac DI in my projects and I usually make ISession as container scoped (one per request). And then every class that uses (directly or indirectly) ISession has to be container scoped or lower (factory scoped == every class usage get's a new instance). If a class that uses ISession is higer scoped (session scoped == singleton) you'll run into problems that you currently have.

If your service is singleton service: At first run the service is created, this service uses ISession, which should be container scoped, and it is on the first run. The next request to service (service is now created) has still a reference to created ISession (which was closed on previous end request), so now it's closed.

I don't recomend using the same ISession that you'll open/close (it's not recomended in the NHibernate documentation), just use container scoped (I do and I don't have any performance issues), or you should create ISession manually in every method in your service like:

using(ISession s = ISessionFactory.OpenSession())
     using(ITransaction t = .....)
....

But that isn't nice at all...

dmonlord
+1  A: 

Please take a look at my answer to my own similar question: http://stackoverflow.com/questions/2377864/wcf-sarparch-underlying-isession-is-closed-after-the-first-call-within-a-reques/2378931#2378931.

@dmonlord is right that the creation of additional session instances within the same request is very cheap in this case.

Sandor Drieënhuizen